8 ms·
> What's wrong with using "isinstance(lst, str)" when necessary? In order for it to be like the Perl6 implementation I would have to check against every type
by hahainternet 11y ago
> What's wrong with using "isinstance(lst, str)" when necessary?
In order for it to be like the Perl6 implementation I would have to check against every type of iterable AFAIK. For example, a generator would be perfectly acceptable, but is there a unique function I could check with hasattr?
Clearly you feel that sigils are intrusive in Perl 6, but having written a bunch I find it quite enjoyable, and they're pretty easy to find in the documentation too. Ultimately, you can use variables without sigils, but with caveats: http://doc.perl6.org/language/variables#Sigilless_variables http://doc.perl6.org/language/variables#Sigilless_variables
- lmm 11y ago> In order for it to be like the Perl6 implementation I would have to check against every type of iterable AFAIK. For example, a generator would be perfectly acceptable, but is there a unique function I could check with hasattr? Define what it is you want - which function you want to use - and then check that (e.g. if you want to iterate over it check for __iter__; if you want to want to test membership check for __contains__). In one part of the code a generator might be acceptable; in another it might not. Which is the point really - array vs scalar seems like a simple, sensible, widely usable distinction on first glance, but it turns out the meaning you actually want is very context-dependent, and a global distinction is a lot less useful than it appears.
- hahainternet 11y agoIf I check __iter__ I consume strings too which is what I'm trying to avoid. Both of you have taken the perspective that this distinction is irrelevant but neither of you have a good answer to this case: > multi sub hi($a) { say "Hello there $a" } > multi sub hi(@a) { hi($_) for @a } > hi("lmm") Hello there lmm > hi(<lmm DonHopkins>) Hello there lmm Hello there DonHopkins Surely this is not so exceptional a use case?
- DonHopkins 11y agoFrom a Python perspective, it looks to me like you're trying to take one particular style of programming (overloading functions) to an extreme (or at least fetishizing it), when it doesn't buy you anything particularly worthwhile, even though is comes at a high cost in terms of cognitive load (and runtime reflection in dynamic languages like Perl, Python or JavaScript). Why should you have to write a special function that knows about looping, when the language already provides several perfectly fine ways to loop? jQuery loves to do that kind of stuff too, slowly sniffing and savoring the arity of its arguments and reflecting on their types at runtime, then doing totally different things like getting, setting, configuring, instantiating, sending messages, and iterating, depending on the number and type of parameters, possibly selecting multiple items even if you only want one, etc... Personally I don't think that style makes code any easier to read or write or guess what it will do, and it sure is a source of a lot of implicit behavior and inexplicable errors. Having one function named "x" that gets x, sets x, iterates over the x dimension, searches for x, or creates x widgets depending on how it's called doesn't make my life any easier. I'm willing to read and type a few more letters to use a set of longer self documenting function names. Using explicit descriptive consistent names, instead of heavily overloading short names and sigils, also makes the documentation easier to search and the IDE easier to use. Explicit is better than implicit or inexplicit. What is so important about the scalar/array dichotomy (which I think is fuzzy, arbitrary and artificial), that they get their own sigils to disginguish them, but you don't also use different sigils to distinguish ints from floats, numbers from strings, arrays from dictionaries, objects from classes, locals from globals, objects from proxies, inputs from outputs from references, etc? The root of the sigil problem is that you quickly run out of unused ASCII punctuation characters to decorate all the concepts you feel the need to distinguish. Of course you could limit identifiers to a single character and require the use of Unicode, like Bjarne Stroustrup suggested in "Generalizing Overloading for C++2000" [1], but isn't it simpler and easier to just use letters that spell out what you mean as words, instead of context sensitive punctuation you have to look up in a legend? I like the way C# uses "in", "out" and "ref" instead of punctuation or emojis. [1] http://www.stroustrup.com/whitespace98.pdf http://www.stroustrup.com/whitespace98.pdf
- raiph 11y ago> (overloading functions) ... comes at a high cost in terms of ... runtime reflection in dynamic languages like Perl, Python or JavaScript In Perl 6 function overloading is generally resolved at compile-time. > Explicit is better than implicit or inexplicit. Explicit what? (jk) > What is so important about the scalar/array dichotomy See my earlier reply to another of your comments. > context sensitive punctuation you have to look up in a legend? Sigils are not context sensitive. > The root of the sigil problem is that you quickly run out of unused ASCII punctuation characters to decorate all the concepts you feel the need to distinguish. The distinction corresponds to major distinctions known to be wired in to human brains: single vs plural, and number vs name. If this seems arbitrary to you perhaps you lack self awareness? (jk)
- lmm 11y agoThat sounds like a really perverse use case to me. Why would you want one function to have two completely different behaviours depending on what it was called with? If you want two different behaviours, write two different functions.
- hahainternet 11y agoI resisted replying to Don as I didn't think he presented any actual argument. The "Write two functions" crew haven't thought this through though. Ultimately, the scenario I came across this in was an atomic transaction decorated function. The data being provided to this function flows through a good 3 or 4 functions beforehand. I also require _single, _list and _listoflists behaviour. This would bloat a 4 function stack into something like 20 different functions. There are also issues with transaction decorators. It just seems crazy to me that Python can't manage this (to me trivial) use case.
- deleted 11y ago[deleted]
- lmm 11y ago> I also require _single, _list and _listoflists behaviour. So it sounds like your needs don't align exactly with perl's sigils anyway (and why should they? For different business requirements you'd categorize differently). > This would bloat a 4 function stack into something like 20 different functions. Not with good language/design. Separate your concerns. Let the difference in behaviour live somewhere more appropriate - either on an object that contains the data (OO style) or in a callback you pass into the function (functional style). > There are also issues with transaction decorators. Decorators have problems yes, that's why I prefer to have a type system handle that kind of thing.
- hahainternet 11y ago> So it sounds like your needs don't align exactly with perl's sigils anyway (and why should they? For different business requirements you'd categorize differently). Indeed but I can write constraints in my function signature to permit this. Hell I can even define something as SpecialList[SpecialKey] if I truly wanted. Perl has a type system. > Not with good language/design. Separate your concerns. Let the difference in behaviour live somewhere more appropriate - either on an object that contains the data (OO style) or in a callback you pass into the function (functional style). Doing this in Python is an exercise in horror, frustration and hatred. Doing it in Perl is the work of a few seconds. That is my point.