Arc Forumnew | comments | leaders | submit | sjs's commentslogin
5 points by sjs 6305 days ago | link | parent | on: New version

Multiple dots pass multiple params to the initial function. To chain you have to group w/ parens.

  arc> (= l '(1 2 (3 4) 5))
  (1 2 (3 4) 5)
  arc> l.2.1
  (3 4)
  arc> (l.2 1)
  4
That 2nd last one translates to (l 2 1), which as you found acts like (l 2).

-----

3 points by mattjones 6305 days ago | link

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.

The present semantics of . make sense though.

-----

8 points by sjs 6305 days ago | link | parent | on: New version

I would prefer it if (cut "abcde" 1 -1) returned "bcd" rather than "bcde". Other than that I like the new cut.

-----

8 points by pg 6305 days ago | link

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.

-----

5 points by pg 6305 days ago | link

Fixed. http://arclanguage.org/item?id=2304

-----

4 points by nex3 6305 days ago | link

Given this, I've changed it to 0-based reverse indexing in the Anarki.

-----

3 points by jules 6304 days ago | link

In Ruby you use Ranges for this.

    (1..4).to_a => [1,2,3,4]
    (1...4).to_a => [1,2,3]
str[a..b] is a substring from a to b, inclusive.

str[a...b] is a substring from a to b, exclusive.

With negative indices:

    str[a..-b] == str[a..str.length-b]
    "abcde"[1..-1] == "abcde"[1..5-1] == "abcde"[1..4] == "bcde"

    str[a...-b] == str[a...str.length-b]
    "abcde"[1...-1] == "bcd"

-----

1 point by carpal 6305 days ago | link

How else would you specify "the end of the string"? -1 seems natural for me. Anything else (0?) makes it kind of foggy.

-----

5 points by nex3 6305 days ago | link

"End of string" is specified by not passing a fourth parameter:

  > (cut "abcde" 1)
  "bcde"
See http://arclanguage.org/item?id=2267.

-----

2 points by maxwell 6303 days ago | link

-0

-----

2 points by nex3 6305 days ago | link

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:

  (cut "abcde" 1 -1)
  (cut "abcde" 1)

-----

3 points by lsb 6305 days ago | link

Nope, Ruby has -1 at the end:

    $ irb
    >> "abcde"[1..-1]
    => "bcde"
    >>

-----

4 points by nex3 6305 days ago | link

Oh, right. That's what I meant.

So, to clarify: I think arc should not do it Ruby-style, but rather have

  arc> (cut "abcde" 1 -1)
  "bcd"

-----

2 points by mec 6305 days ago | link

How would you then decide 0 0?

  arc> (cut "abcde" 0 0)
  "a"
  arc> (cut "abcde" 0 0)
  "abcde"
-1 should deffinitly refer to the last elemental or I don't see a way to get it.

-----

3 points by nex3 6305 days ago | link

(cut s 0 0) should return the empty string, just like (cut s 1 1) and (cut s 42 42). Which it does in either implementation.

-----

2 points by vincenz 6305 days ago | link

Then you would need -0 to get the full string. You're not making sense.

How do you propose to get "bcde" from "abcde"?

Either you need -0, or your final 0 is ambiguous.

-----

3 points by nex3 6305 days ago | link

No you don't - the full string is the default.

  > (cut "abcde" 1)
  "bcde"

-----

3 points by tokipin 6305 days ago | link

i was thinking that too, but how would you do it dynamically (eg with variables) ?

  (cut "abcde" begin end)
what would i need to put in end to get the full string? nil?

-----

3 points by sjs 6305 days ago | link

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.

-----

2 points by nex3 6305 days ago | link

If you absolutely need to do that, you can just use (len str).

-----

3 points by akkartik 6304 days ago | link

Yup. Which is how python does it.

-----

2 points by jules 6304 days ago | link

    $ irb
    >> "abcde"[1...-1]
    => "bcd"

-----

4 points by sjs 6305 days ago | link | parent | on: New version

  arc> (= s "abc")
  "abc"
  arc> s.1
  #\b

-----

2 points by sjs 6305 days ago | link | parent | on: New version

I think it makes sense.

  arc> (def add (x) [+ x _])
  #<procedure: add>
  arc> (map [prn:add.40:idfn _] (range 1 5))
  41
  42
  43
  44
  45
  (41 42 43 44 45)

-----


I think it's pretty important that we be able to write

  arc> ((fn ((o o o)) o) "bar!")

-----

2 points by sjs 6306 days ago | link | parent | on: Yet another []-Syntax Proposal

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.

  arc> (macex '[nil])
  (fn (_) (nil))
  arc> ([nil] 3)
  Error: "Function call on inappropriate object nil ()"

-----

2 points by absz 6306 days ago | link

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.

-----

1 point by sjs 6306 days ago | link

Thank you for the correction. While spouting all that I forgot about the extra stuff that make-br-fn does.

-----

1 point by almkglor 6306 days ago | link

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.

-----

1 point by absz 6306 days ago | link

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.

-----

1 point by sjs 6307 days ago | link | parent | on: [patch] Break out of loops early

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.

-----

2 points by almkglor 6306 days ago | link

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").

-----

3 points by sjs 6307 days ago | link | parent | on: Understanding macros.. is this a bug ?

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.

  (each (path dest) redirects* (defopr path req dest))
expands to: [via (macex1 '(defopr path req dest))]

  (each (path dest) redirects* (do (t! (redirectors* (quote path))) (defop-raw path (gs2429 req) dest))
which expands to:

  arc> (macex1 '(defop-raw path (gs2431 req) dest))
  (= (srvops* (quote path)) (fn (gs2431 req) (let gs2433 (msec) (do1 (do dest) (save-optime (quote path) (- (msec) gs2433))))))
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:

  (each (path dest) redirs* (eval:apply defopr (list path 'req dest)))
I think what's really needed is a function that does what defopr expands to, which can be called at macro expansion time and runtime alike.

On Lisp[1][2] and PCL[3] are useful here.

[1] http://www.bookshelf.jp/texi/onlisp/onlisp_8.html

[2] http://www.bookshelf.jp/texi/onlisp/onlisp_9.html

[3] http://www.gigamonkeys.com/book/macros-defining-your-own.htm...

http://www.apl.jhu.edu/~hall/Lisp-Notes/Macros.html (section 4, doesn't give much in the way of solving the problem though)

-----

1 point by sjs 6307 days ago | link | parent | on: Tagging

> 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. ;-)

-----

1 point by almkglor 6307 days ago | link

Actually, what I meant is that (t ...) could not be redefined.

-----

1 point by sjs 6306 days ago | link

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.

-----

More