Arc Forumnew | comments | leaders | submit | evanrmurphy's commentslogin
1 point by evanrmurphy 5660 days ago | link | parent | on: cdr vs. nthcdr 1

Very helpful, thank you.

Edit: Rest of comment became post at http://arclanguage.org/item?id=11481

-----


Yay! I was playing piano today and had the same train of thought:

  Damn this notation is repetitive, it feels like assembly. I wish
  I had a lead sheet for this Chopin Nocturne, or something even
  more abstract. Wait a minute... wasn't there something on Arc
  Forum about this??
Please keep us posted, I'd like to follow your developments on this!

-----

1 point by evanrmurphy 5662 days ago | link | parent | on: Check function or macro definition?

I'm finding posts now (e.g. http://arclanguage.org/item?id=9801) referencing an Anarki function 'src that may be what I'm looking for, but I haven't tried it yet.

-----

1 point by evanrmurphy 5662 days ago | link

I got Anarki and have been experimenting with 'src. It appears to be exactly what I was looking for:

  arc> (src map1)
  (from "arc.arc")
  (def map1 (f xs)
    (if (no xs)
        nil
        (cons (f (car xs))
              (map1 f (cdr xs)))))t
Handy that it prints the source file's name too. It even works for functions defined at the REPL:

  arc> (def testfn () (pr "this is testfn"))
  #<procedure: testfn>
  arc> (src testfn)
  (def testfn nil
    (pr "this is testfn"))t
'src will be very useful to me, and it seems the natural extension of the implementation-as-specification idea put forth in the tutorial:

  The definitions in arc.arc are also an experiment in another way.
  They are the language spec.  [...]
  It may sound rather dubious to say that the only spec for something
  is its implementation.  It sounds like the sort of thing one might
  say about C++, or the Common Lisp loop macro.  But that's also how
  math works.  If the implementation is sufficiently abstract, it
  starts to be a good idea to make specification and implementation
  identical.
Now I can access the details of the implementation--which is the specification--right from the REPL. Thanks, shader! (I'm presuming you're the author, in which case would you mind explaining the trailing 't printed on calls to 'src?)

-----

2 points by waterhouse 5661 days ago | link

I, my curiosity provoked, looked through Anarki, and I can answer your question: t is the value returned by 'src, by virtue of being the value returned by 'ppr. (A call to 'src expands to a call to 'ppr-source, and the last expression in 'ppr-source is (ppr source.name). (Actually it's source* but putting that in italicizes the rest of this message.)) It is 'ppr by itself that has this annoying property.

  arc> (ppr '(def meh (x) (list (+ x 2) (+ x 3))))
  (def meh (x)
    (list (+ x 2) (+ x 3)))t
It would be nice if ppr printed a newline at the end. In fact, I'm almost certain it should, because a) it seems one would use it to print code for human eyes, and nothing else, b) readable code does not generally have separate expressions on the same line, and c) anything printed on one line is by definition not prettily formatted and can be pr'd instead of ppr'd.

I would like to simply redefine ppr, thus:

  (let old-ppr ppr (def ppr args (apply old-ppr args) (prn))
Unfortunately, ppr is apparently defined in terms of itself. And when recursive functions get redefined, the calls to what used to be themselves get redefined too. Using the above makes ppr print out way too many newlines:

  arc> (src defop)
  (from "srv.arc")
  (mac defop
  
       (name parm . body)
  
       (w/uniq gs
  
               (quasiquote (do (wipe (redirector* '(unquote name)
  ...
It's just horrible. Simple hack fix: go to pprint.arc, replace all instances of "ppr" with "ppr-fn", and then add (def ppr args (apply ppr-fn args) (prn)). Or just put up with the t.

-----

3 points by shader 5661 days ago | link

Yep, the trailing t and lack of newline are due to ppr.

Fortunately, I also happen to have an alternative version of ppr on anarki, under the lib folder, which has just been updated to handle multiple expressions and print newlines.

Just pull anarki again, and use

  (load "lib/ppr.arc")
It should redefine sp, len, and ppr, and make source code printing much more readable than the pprint.arc version ;)

-----

1 point by akkartik 5662 days ago | link

Looks like it didn't make it across to the arc3 branch (http://github.com/nex3/arc/blob/arc2.master/arc.arc) but it's easy enough to port.

Update: I stand corrected; it is indeed in anarki: http://github.com/nex3/arc/blob/master/load/help.arc. Shader, is this the version you wrote?

-----

1 point by shader 5661 days ago | link

If it's not exactly what I wrote, it's still probably the correct version to use. I pushed my code to anarki but rntz handled the porting of most libraries to arc3. Any changes are probably for the better.

-----

2 points by evanrmurphy 5662 days ago | link | parent | on: Check function or macro definition?

I found this paragraph in the tutorial that I thought could be related:

  There's one thing you can't do with functions that you can do with
  data types like symbols and strings: you can't print them out in a
  way that could be read back in.  The reason is that the function
  could be a closure; displaying closures is a tricky problem.
Does this mean what I'm requesting isn't possible at the moment, or is it a different idea?

-----

2 points by shader 5660 days ago | link

This is a different idea. He's pointing out that in general functions can't be printed out, because the function could be represented by something very complicated and hard to print. His example, closures, are function objects that were defined in a lexical context that is relevant to their function. Merely knowing their source code won't be helpful, since two identical looking functions can behave very differently.

If you knew it was a closure, you could probably substitute the variables values for their names, and then print the resulting code, but that requires that you know both what the values are, and the fact that the function is a closure.

Also, I think he's describing the more complicated concept of reverse engineering the actual data type of a function, and printing a representation of it. Taking code that runs, and turning it into code you can read is not an easy challenge. I dare you to macex even a simple function. Taking that and turning it back into something you can read, with meaningful names, is impossible (I think).

At any rate, with 'src I took the shortcut of storing the source code in a table every time a function is defined. This has the disadvantage of only working for global, named functions defined with a small set of function creators (def and mac, mainly) since it uses a global name table. If it stored the string representing the code with the function object itself, it would probably be able to handle local, un-named functions as well, but would still only work with select function creators. This is mainly because you wouldn't want to see the crud added by defop over defop-raw, etc.

So, in general, displaying executable code in a human-readable format is an immense challenge. The more about the original function definition you keep around at run-time, the more easily you can represent it in a human readable form. The hack that is 'src achieves pretty function printing at the cost of storing the whole source code of global functions in a table at run-time. It still lacks a lot of information, and doesn't cover functions defined in local contexts, but it achieves at least a portion of the goal of exploratory, interactive programming.

-----

1 point by evanrmurphy 5656 days ago | link

Thanks for such a thorough explanation, shader. Gives me more to grok. :)

-----

1 point by shader 5655 days ago | link

Supposing you knew that a function was a closure, couldn't you print it out as

  (= fname
    (with (var1 val1 var2 val2 ...)
      (fn (arg1 arg2)
         ...)))
When read in, it should produce an identical closure. The problem is knowing under what variables the function is closed in the first place.

It would be nice if there was more information about objects and source code in arc. I.e. the source codes of functions, the current namespace, the variables captured in a closure, the stack trace, etc.

-----


I very much look forward to trying this!

Update: The example works for me exactly as you say. Thanks so much for doing this.

-----


Exciting stuff, palsecam. Though I've been really pleased by how quickly srv + app.arc has let me get some working apps going ("OMG so easy" as you say), I do foresee needing more control in the future. Will definitely consider http + web.arc.

-----

1 point by evanrmurphy 5672 days ago | link | parent | on: Re: How to upload files?

That looks interesting, thanks.

  > It requires Flash and any backend development language.
I'd certainly prefer an implementation that didn't depend on Flash, but this may be a "beggars can't be choosers" type of situation. :)

-----

2 points by thaddeus 5672 days ago | link

I believe this one does not use flash...

http://valums.com/ajax-upload/

-----

2 points by shader 5672 days ago | link

I'm not sure that either of those are what he's looking for. Both seem to be different ways of displaying the upload form to the user, but neither seems to change the way that the back end handles the file.

It sounds like he wants a way for arc to receive an uploaded file in an http request, and do something with the data, rather than a way to display an upload form.

-----

1 point by evanrmurphy 5672 days ago | link

Yes, that is correct.

-----

1 point by evanrmurphy 5673 days ago | link | parent | on: Permission Denied; errno=13?!

I was having a duplicate of system42's problem, and commenting out line 14 fixed it for me. Thank you, aw!

-----


Very instructive. Thank you for doing such a thorough analysis.

',r from your snippet

  (mac rdefop (r)
    `(defop ,r req (rpage ',r)))
was a realization for me. Never thought of quoting a comma'd symbol in a backquoted expression before, but I like knowing it's possible. Do you find yourself doing this much, or is there usually something simpler like aw's solution available to make it unnecessary?

-----

2 points by fallintothis 5673 days ago | link

Happy to help.

Oh, yes, quoted-unquotes are done pretty often.

  $ grep -c "'," {arc,code,html,srv,app,news}.arc
  arc.arc:17
  code.arc:1
  html.arc:6
  srv.arc:9
  app.arc:1
  news.arc:7
For example, the Arc built-in obj is a macro that makes a hash table with automatically-quoted keys.

  arc> (= h (obj a 1 b 2))
  #hash((b . 2) (a . 1))
  arc> (h 'a)
  1
  arc> (h 'b)
  2
It's defined like so:

  (mac obj args
    `(listtab (list ,@(map (fn ((k v))
                             `(list ',k ,v)) ; note we unquote k, then quote it
                                             ; so we're quoting the value of k
                           (pair args)))))
That way, the above (obj a 1 b 2) expands into

  (listtab (list (list 'a 1) (list 'b 2)))

-----

1 point by evanrmurphy 5673 days ago | link

Thanks again.

-----

1 point by thaddeus 5673 days ago | link

dito

-----


Very helpful, all of you. Thanks again for your time and the great advice.

@conanite This will definitely help me take advantage of the repl better in the future.

@thaddeus

  > I think you intended to do this: [...]
Yes, exactly!

  > And don't ask me why the following works - it's a brutal hack! [...]
Thanks for posting this. I'm realizing more and more how much better it is to have a brutal hack that works than some thoughtful code that doesn't.

@aw I used a variation of your code (with ?route=) in my solution. Much more elegant than what I was trying to do, thank you.

-----

More