5 ms·
Separate from anything else, I'm ... concerned ... at the idea of ints being iterable, because it seems like something I'd be much more likely to invoke acciden
by mst 2y ago
Separate from anything else, I'm ... concerned ... at the idea of ints being iterable, because it seems like something I'd be much more likely to invoke accidentally than intentionally and then wonder wtf my program was doing. I'd prefer to have to write something like
(reduce + (range 1 3) 0)
and if you find yourself wanting the natural number iteration regularly maybe
(^upto (n) (range 1 (- n 1)))
as sugar.
This concern brought to you by e.g. the great pain induced by the difference between
for x in "foo":
and
for x in "foo",:
in python, for example.
It may turn out in practice that a lispy language and/or programmers who make different mistakes to me will make it not an issue ... but were it -my- project I'd probably comment out the iterator implementation for int and see if its absence annoyed me enough to decide it was worth bringing back.
(when perpetrating language myself I often find that some of my favourite bits of clever don't pass the 'annoyed me enough' test and end up as documentation examples or similar in the end instead ... hopefully you have better luck ;)
- codr7 2y agoNoted, I feel like I need more use cases and experience to say for sure. Some way of forming ranges is planned anyways.
- mst 2y agoYeah, 'int is iterable' triggered "oh that's cute!" immediately followed by "... and the exact sort of cute I often find irresistably tempting myself and then regret later." My current thing in progress has basically all of its temptation points already spent because I decided I was going to make it fexpr based, but I'm very definitely having fun with that so far - "no special forms required" makes for some interesting possibilities. (kernel-lisp and kernel-thesis in /lisp/ are worth looking at if fexprs sound interesting, though I'm on the pragmatics side of things and will not pretend I came anywhere close to understanding the $vau calculus part)
- codr7 2y agoA certain level of helpfulness is nice though, Ruby and to a somewhat lesser extent Perl get that part right. I guess Perl could be seen as a warning example of what happens if you go all in. Yep, I've been on a ride down the fexpr implementation hole previously; which is another reason I've been delaying user macros; still processing the experience.
- mst 2y agoThere's a bunch of stuff in perl that's best restricted to one-liner or short script usage - i.e. the sort of cases where you're using it for the early inspiration super-awk purposes. Writing perl as a programming language is, I find, a very different dialect, and perhaps amusingly one in which I rely on function composition, closures and block scoping heavily due to also loving lisp - javascript's 'let' behaves very similarly to perl's 'my' and I find it ... difficult ... to deal with python or ruby for any length of time since their scoping is "stuff randomly pops into existence at function scope" and, just, aaaaa. Perl of course can't really have macros, but it does have the ability to define custom (also block scoped :) keywords which can allow one to achieve similar results - see e.g. https://p3rl.org/Keyword::Declare https://p3rl.org/Keyword::Declare for a demonstration built on top of that functionality (there's also a code rewriter called Babble but I got distracted so while it works, it's woefully underdocumented, keep forgetting to get back to that). I've always had a fondness for the "building the language up towards the problem" style of programming (I wrote the first ever proof of concept for custom perl keywords, though that code has happily long since been obsoleted by people who knew what they were doing) which has led me to 'fexprs for making DSLs' since those are usually building up a config structure or similar which makes fexprs' being tricky to optimise less of an obstacle. (also with fexprs I don't have to limit myself to 'block in front' ala perl or 'block at the end' ala ruby/elixir (though it's amazing how much mileage elixir gets out of its macros, Kernel.ex is well worth a read if you're so inclined))
- kazinator 2y agoIntegers are also iterable in TXR Lisp. But in a different way; you get an infinite sequence starting from the value. 1> [mapcar list '(a b c) 10] ((a 10) (b 11) (c 12)) This crops up on a regular basis in my coding, removing verbosity; I don't regret the decision. It's one of the "take alongs": something to repeat in a future language.
- codr7 2y agoThe duality of meaning (is it from or to the specified value) actually speaks against the feature for me, you just ruined it :) Or fixed it, depending on which way you lean.
- kazinator 2y agoIt would not be often useful to have it count up from 1 or zero up to or below the value; I would not have designed it that way. In many situations you don't know the upper limit of what is enumerated; it comes implicitly from the lengths of other sequences or in other ways. It's also less inefficient, because the value has to be converted to an iterator object that knows about the range, and keeps track of the state. In TXR Lisp, certain objects are self-iterable, like characters, numbers and good old conses. 1> (iter-begin "abc") #<seq-iter: a031a10> 2> (iter-begin 3) 3 3> (iter-begin '(a b c)) (a b c) To iterate a string, we need to obtain a seq-iter object, but for 3 and (a b c), we do not. With these objects, we have all the state we need in order to iterate. 4> (iter-more 3) t 5> (iter-item 3) 3 6> (iter-step 3) 4 7> (iter-more '(a b c)) t 8> (iter-item '(a b c)) a 9> (iter-step '(a b c)) (b c) 10> (iter-more *1) t 11> (iter-item *1) #\a 12> (iter-step *1) #<seq-iter: a031a10> 13> (iter-item *1) #\b iter-step may or may not destructively update its argument, so you always have to capture the return value and forget about the original. You can see how for a list, iter-more is equivalent to (not (null ...)), iter-item is just car, and iter-step is just cdr. There is also lazy processing in TXR Lisp. E.g. lazy mapcar which is mapcar*. The following will only read the first few lines of the syslog, returning instantly: 14> (take 3 [mapcar* cons 1 (file-get-lines "/var/log/syslog")]) ((1 . "Jul 23 00:09:54 sun-go systemd[1]: openvpn@client.service: Service hold-off time over, scheduling restart.") (2 . "Jul 23 00:09:54 sun-go systemd[1]: openvpn@client.service: Scheduled restart job, restart counter is at 1044619.") (3 . "Jul 23 00:09:54 sun-go systemd[1]: Stopped OpenVPN connection to client."))