Yep, thanks. It would be cool if there were an abbreviation for that, since it's fairly common. Eg l.2%1 (% randomly chosen) => ((l 2) 1). Some may say that goes too far toward a parentheses alternative for all sorts of things, but on the other hand data structure access is one of the clumsier parts of Lisp.
Hmm, yes, so would I. I should fix that. I just did what Emmett suggested, which must have been based on Ruby, but it doesn't actually seem like a good idea.
Agreed. Ruby does it the other way ("abcde"[1..-1] is "bcd"), but that's only because there's no other way to specify "until the end." But that's the default in Arc; the following are equivalent right now:
Both nil and (len str) work. I see both sides of the argument as counting from -1 eliminates the 0 corner case.
I like indices that are intuitive with literal numbers. Counting from 0 at one end and from 1 at the other is jarring. When -1 points to the end of string rather than before the last char (cut str 0 (- (len str))) returns the first char instead of the empty string.
With -1 -> before last char:
(def chop ((o str "abcdef"))
(pr "Chop how many chars off the end of \"" str "\"? ")
(= n (coerce (cut (readline) 1) 'int)) ; bug in readline prepends #\newline
(prn "Chopped: \"" (if (is n 0) str (cut str 0 (- n))) "\"")) ; handle corner case
With -1 -> end of string:
(def chop ((o str "abcdef"))
(pr "Chop how many chars off the end of \"" str "\"? ")
(= n (coerce (cut (readline) 1) 'int)) ; bug in readline prepends #\newline
(prn "Chopped: \"" (cut str 0 (- -1 n)) "\"")) ; no corner case, but there's this -1 there
I probably made a stronger argument for -1 pointing to the end of string as it leads to shorter code.
I think it's important to distinguish between what's read and what's executed. The reader translates [] into (make-br-fn '()), which expands to (fn (_) ()). I am totally stumped as to what (fn (_ (fn (_) nil)) (_ 'bar (fn (_) nil))) could or should mean. It seems as if you are thinking about [] as a symbol in [_ 'bar []] => (fn (_ []) (_ 'bar [])), but that is confusing. When thinking about [...] on this level we should be thinking in terms of the actual sexps evaluated. Translating [] to (fn (_) nil) outside [...] and to something else inside them is a road to madness and some serious reader hacking.
[] never expands to a function of zero arguments. ([]) is an error, too few arguments.
[nil] is not the always nil function. I had the same misconception at first, that the ... in [...] is the body of the fn, but (...) is the real body. The [] are simply replaced with (), so the body is always a function application and never an atom, save for the special case of [] -> () -> nil. [] and [idfn nil] are 2 always-nil functions, but the fact that [] is always nil is a consequence of [] expanding to (fn (_) ()) and nil being the empty list in Arc.
I agree with your general premise, but I have one correction--in arc0.tar, [...] expands directly to (fn (_) (...)). It's only in the git repository that it expands to (make-br-fn (...)) (which (semi-incidentally :P) I added, but that's not the point). Regardless, your point still stands, and I agree.
make-br-fn allows you to use _1 _2 ... _n (it searches for the n AFAIK) as well as __. If you use _n you get a n-arity function. If you use _n and __, you get a >=n-arity function, with __ containing the rest. I have a few reservations about whether it handles checking of free variables properly but I haven't actually dived into the code.
make-br-fn doesn't search for a literal _n, but it searches for anything matching the regexp /_(\d+|_)?/, except for anything of the form /_0+/. The free-variable checking code is based off of problems I did while working through Essentials of Programming Languages by Friedman, Wand, and Haynes, and it certainly shouldn't break in most common cases (especially since most common cases won't bind any extra variables). A second set of eyes is probably a good idea, though.
I was thinking the same thing this morning actually. Probably not something common enough to warrant wrapping every loop. I like the breakable idea of yours.
Could be implemented. I'm in the office right now so I can't use arc here (mandatory windows pc, not to mention a shared internet terminal); it would be possible to just add it into arc.arc, although with a seriously good docstring.
(mac breakable (expr)
" Creates a control structure which can be exited by
calling `break' with a value to be returned. To
use, add `breakable:' before the control structure,
e.g. (breakable:while t (aif (something) (break it)))
See also [[catch]] [[point]] [[compose]] [[while]] "
`(point break ,expr))
Indeed, and it does when you call compose directly. The good news is that if you name the string it works as expected.
arc> (= s "abc")
"abc"
arc> (prn:s 1)
b
#\b
The reader splits expressions such as (prn:"foo":[idfn _] 2) into (prn: "foo" : (make-br-fn (idfn _) 2). You could check for trailing : in the car or a leading : in the cadr, and if found then wrap strings and tables in id fns. Stash them (as well as literal fns and make-br-fns) under a uniq name. Finally, add the uniq name to the end of the head symbol and repeat if necessary. This would be done before expand-ssyntax. I'm not sure it's worth the effort.
I think the final result would be very cool, mostly to allow things like (prn:[_ 3] "hello").
The first each loop does change srvops, it adds a redirect from "path" to "dest" (literally).
Macros are expanded prior to evaluation. This seems strange while typing into the repl because we tend to think of macros as functions most of the time. macex and macex1 are useful.
Every iteration of the loop performs the same defopr.
I've come across this problem of wanting to run macros at runtime in order to evaluate the args first, but I think it is due to a misunderstanding of macros. This works, but it's an ugly hack:
> In any case, the only minimum requirement would be that (t ...) would validly return a "useless" value without any side-effects and cannot be redefined.
Well, you have the last part of your wish. t is the symbol representing true in Arc and cannot be redefined. ;-)
I know, hence the ;-). All I was saying is that you have to choose a symbol different from t, as you will not be able to define a meaning for (t ...), let alone redefine it.