Arc Forumnew | comments | leaders | submit | evanrmurphy's commentslogin
2 points by evanrmurphy 5376 days ago | link | parent | on: Making keyword args read better

Official arc has optional arguments, designated by `o` in parameter lists:

  arc> (def hello ((o name "stranger"))
         (string "Greetings, " name "!"))
  #<procedure:zz>
  arc> (hello)
  "Greetings, stranger!"
  arc> (hello "Steve")
  "Greetings, Steve!"
The difference between this and keyword parameters is that, with the latter, the caller of a function can bind its arguments to the function parameters in any order by specifying each argument's keyword. In akkartik's system, this looks something like:

  wart> (def hello (? greeting "Greetings" name "stranger")
          (string greeting ", " name "!"))
  #<procedure:zz>
  wart> (hello)
  "Greetings, stranger!"
  wart> (hello :greeting "Hello" :name "Steve")
  "Hello, Steve!"
  wart> (hello :name "Steve" :greeting "Goodbye")
  "Goodbye, Steve!"
But this doesn't work in official arc.

-----


It's ironic because if only Arc Forum supported notifo, pg might be aware of our plea! :P (Although not really, because he would probably just be notified of responses to his own comments.)

I know for a fact that SteveMorin was already aware of the post you linked to (because he emailed me about it). I think he's casting another vote.

-----

3 points by thaddeus 5376 days ago | link

A long time ago I made some asinine comment about PG not checking up on his own forum to fix a bug (lol - there were so few people on this forum, that his voting algorithm determined we were all playing three way voting rings then and stopped counting ~ more like a three person voting circus to me - lol).

Anyway, to which, aw - instead of complaining about it, just sent him an email. pg responded fairly quickly with a bug fix and all. Doh!

So maybe just email him and you'll get what you want.

-----

1 point by evanrmurphy 5376 days ago | link

lol thanks for the anecdote. I'll plan to email him, then. :)

-----


Feel free to steal from the previously written html.arc alternatives if you find anything useful:

- almkglor's whtml.arc: https://github.com/nex3/arc/blob/arc2.master/whtml.arc

- jazzdev's sml.arc: https://github.com/nex3/arc/blob/master/lib/sml.arc

- my html.arc: http://arclanguage.org/item?id=12010

As webapps become increasingly javascript-driven though, I think the need to write html decreases. That's why I'm personally more interested in lisp->javascript now than lisp->html (and also why I haven't done much with the html.arc fork linked above since posting it).

-----

2 points by evanrmurphy 5377 days ago | link

From hasenj's deleted comment:

> that's why I'm considering playing with coffee-script/node.js next

Yes. That's where I'm at.

I think CoffeeScript is wonderful. If only it had macros we'd be set. I've made a bit of progress on that front (i.e. https://github.com/evanrmurphy/SweetScript) and will post about it soon.

Email me and we'll talk about javascript, hasenj!

-----

3 points by fab13n 5367 days ago | link

> If only it had macros we'd be set.

Working on this: https://github.com/fab13n/parsec-coffee-script

It's a port of metalua (https://github.com/fab13n/metalua), a macro + syntax extension system for Lua. Given that CS's grammar is more exuberant than Lua's, the parser combinator library that supports runtime syntax extension requires much more work.

-----

1 point by hasenj 5377 days ago | link

> I think CoffeeScript is wonderful. If only it had macros we'd be set.

It is.

I'm not sure about macros, but having something similar to s-expressions would be nice.

The only thing still kinda holding me back is html templating. Doing them in {{ templates }} like that was a horrible experience with Django. Jinja2 made it a bit more bearable, but {% endtag %} kind of stuff is still bad.

-----

1 point by evanrmurphy 5377 days ago | link

> I'm not sure about macros, but having something similar to s-expressions would be nice.

Yes, s-expressions too. But what aren't you sure about regarding macros. (And what do you see as the benefit of s-expressions besides macros?)

> The only still kinda holding me back is html templating. Doing them in {{ templates }} like that was a horrible experience with Django.

Are you referring to http://mustache.github.com/ ?

-----

1 point by hasenj 5377 days ago | link

> what do you see as the main benefit of s-expressions besides macros?

For this specific problem (html generation), the advantage of s-expressions is you can build a tree with it, with minimum boilerplate. For example, the closing tag is just a ')'. Also, again for this specific problem, because we're mostly just generating strings, just having functions would probably suffice.

> Are you referring to http://mustache.github.com/ ?

Yea. I was looking for html templating system for Node, and that was about the only thing that came up.

-----

2 points by garply 5376 days ago | link

Hey Evan,

What's the status of your arcscript? Do you have something usable? I'd love to use it if you feel like sharing.

-----

2 points by evanrmurphy 5376 days ago | link

Thanks for asking! It's in active development at https://github.com/evanrmurphy/SweetScript. I just added some install and run instructions so give it a go!

I'd love for you to use it and to have your feedback. Of course, it's still unstable, poorly documented, etc. Please open lots of issues and send me emails to the tune of "Why the hell <x>?". I'll always try to give you a personal response.

Also, if you're interested in working together on it, or just forking it and changing a bunch of stuff, that could be really neat! :)

-----

2 points by evanrmurphy 5377 days ago | link | parent | on: Multi-arg anonymous functions broken?

The OP is presuming that anarki hacked the bracketed functions to accept multiple arguments. I remember reading that somewhere as well, but since I haven't tried using the feature before I don't really know.

-----

2 points by shader 5377 days ago | link

If that is the case, then he needs to use the _ and _1, instead of _.0 and _.1 to access the separate arguments, if I remember correctly.

_0 and _ are synonymous, I think.

-----

1 point by garply 5376 days ago | link

Thanks, it seems like my brain was scrambled last night. _0 and _1 (or _a and _b) are the appropriate pieces of code. But the real problem was that I was operating out of an arc directing that was lacking a load/ directory. Thus I was missing the make-br-fn.arc file. Fixed now. Thanks guys!

-----

1 point by garply 5376 days ago | link

It works, although I'm still not sure exactly where the _0 _1 or _a and _b components are implemented.

-----


> Too many tricks. Too clever.

Agreed. I find the code in html.arc to be very confusing. When I look at it, I tend to feel either critical of the code or that pg must be way smarter than me.

I posted more-or-less the same question a few months ago [1]. From shader's comment there:

> By printing directly to stdout you don't get to have as many tail calls, but you don't have to worry about much complexity when it comes to aggregating output or adding new functionality. A simple pr is all it takes to add output, and you don't need to worry much about context.

This relates directly to your closing question:

> Wouldn't it be easier if everything just returned strings and then these strings were concatenated together?

If everything returns strings, it's nontrivial to make your functions composable. You can't stack them on top of each other unless they take strings as their arguments as well. But then you can only stack them on top of each other, not treat them as user-facing functions. So you have to keep at least a couple groups of functions with strictly different roles. Perhaps you've already thought of this.

---

[1] http://arclanguage.org/item?id=12049

-----

3 points by hasenj 5377 days ago | link

I'm under the impression that html.arc is based on hacks that PG used while doing viaweb in common lisp.

If so, then this way of building html is probably a performance hack.

> If everything returns strings, it's nontrivial to make your functions composable.

Really?

> You can't stack them on top of each other unless they take strings as their arguments as well.

Exactly.

Isn't that how all html templating schemes work? A python example is Jinja macros[1]

Composing html elements as functions that take strings and return strings is the only way that makes sense to me.

> But then you can only stack them on top of each other, not treat them as user-facing functions. So you have to keep at least a couple groups of functions with strictly different roles. Perhaps you've already thought of this.

I'm not really sure what you mean.

[1] http://jinja.pocoo.org/templates/#macros

-----

5 points by thaddeus 5377 days ago | link

Personally I like how it currently works:

1. String operations are costly, printing to stdout is not. ie. if I need to run a function to generate some numbers, dumping them at the right time to stdout has very little overhead, having to weave them within a string operation costs so much more.

2. There's a benefit having a web server that pushes changes out to the browser incrementally via stdout. The user doesn't have to wait for the entire operation to complete to see the results. ie, what if the last half of your server operation, provides no output for half of your users?

3. Adding on to #2, for troubleshooting and iterative development purposes, it's nice to see a portion of the output within your browser to see how far a long your operation got, results wise, before it hit an error.

-----

2 points by hasenj 5377 days ago | link

Sounds like a case of sacrificing expressiveness for performance. Somehow I think this goes against the design principles of arc.

For #2 and #3, the output has to be so huge before you reap this benefit. Most apps don't have this property, and if they did, I'd think there's a deeper design problem. Such problems can be better solved using asynchronous javascript requests (aka ajax).

-----

3 points by thaddeus 5376 days ago | link

> For #2 and #3, the output has to be so huge before you reap this benefit.

I think it's, more so, a case of how complex your code is rather than how big your output is. I can have 200,000 lines of code that outputs 20 small numbers. Knowing it hit the 8th number and what that number is can be huge for both a user and for development.

Also - maybe it's just me, but having partial output has helped me with 20 lines of code and very little output.

> Sounds like a case of sacrificing expressiveness for performance.

Also - maybe it's just me, but I've been spending most of my time with Clojure, where the Ring web server requires a string for an output. I found my code became less expressive than arc.

So, for Clojure, I actually wrote my own html framework to mimic arc's functions that write to stdout, then just put a big wrapper on it at the end: (with-out-str (println "stuff")). Next I plan to see if I can hack Ring@Jetty to pipe the output too.

Kinda funny, I went to Clojure and did the opposite of you. :)

-----

1 point by hasenj 5376 days ago | link

Well then, back to my original question: how do you compose elements together?

-----

3 points by thaddeus 5374 days ago | link

So I gave it another whirl and here's my attempt to capture the essence of you're problem:

For example you would like to do this:

  [1] arc> (spanclass "links" 
             (string "use this link:" 
               (tag (a href "http://mydomain.com/the-place-to-go") "here"))
And have it return this:

  <span class="links">use this link:<a href="http://mydomain.com/the-place-to-go">here</a></span>
and your first attempt might be something like this:

  [2] arc> (spanclass "links" 
             (pr:string "use this link:" 
               (tag (a href "http://mydomain.com/the-place-to-go")(pr "here")))
only you find it returns the wrong results:

  <span class="links"><a href="http://mydomain.com/the-place-to-go">here</a>use this link:</span>
so now you're probably thinking by having functions return strings like this:

  [3] arc> (tag (a href "http://mydomain.com/the-place-to-go") "here")
  "<a href=\"http://mydomain.com/the-place-to-go\">here</a>"
then the original function [1] would have worked.

Instead, with arc, you need to approach your code differently. You need to think about the timing of when things are happening rather than having available 'string-things' that you can compose by nesting your functions.

So with arc [1] needs to become [4]:

  [4] arc> (spanclass "links" 
            (pr "use this link:")
            (tag (a href "http://mydomain.com/the-place-to-go")(pr "here")))

  <span class="links">use this link:<a href="http://mydomain.com/the-place-to-go">here</a></span>
Am I capturing it correctly? Does this answer your question on how I compose my functions?

-----

1 point by thaddeus 5376 days ago | link

I've re-looked into your original questions, in an attempt to provide a meaningful response, but I find the scenario's are not concrete enough.

For example I find the re-arrange function a little vague.

i.e. could you not:

  (def something (a b c)
      (output b c a))
Could you provide an real-case like example where you feel you can show a clear difference? For, I found, even your row example can easily work with stdout inside a function rather than using pg's macro. ie. Not liking how some of the existing functions/macros work doesn't mean string weaving is the answer.

And row is a pretty crappy example, even when I built my Clojure library, I ditched pg's implementation and went with a more useful implementation, yet it still uses stdout. You have to remember that pg only built those macro's to support his specific cases in his HN app.

Also, for > Too many tricks. Too clever.

Well it's a library, it's not expected you're crafting macros for your regular coding. I mean there's only so many HMTL cases you need to handle right? So if the library is complete, providing (macro's or not) succinct code and faster results, then it's probably good to have - tricks inside or not.

-----

1 point by shader 5377 days ago | link

html.arc isn't that long, you could probably rewrite it using strings pretty quickly if you wanted to. And I'm sure that others using arc would be happy to have a string based system if you wrote it. There's no reason we can't have two alternate methods of generating html in arc.

-----

3 points by hasenj 5377 days ago | link

Here's what I cooked up during the past coupla hours.

It doesn't do much, but builds a base for writing composable html elements.

It reuses the 'tag macro from html.arc as a base (no need to rewrite that part) but captures the output in a string (using 'tostring, of course). Thus the 'btag function becomes the base to build and compose html tags.

The few extra functions included serve as example of how to compose tags.

For example, 'hstack stacks its arguments horizontally using table columns.

'prn expressions are interspersed in between code blocks. They serve as examples, and I was using them for debugging.

    (def listify (arg)
         (if (acons arg) arg (list arg)))

    (def btag (tagspec content)
         "Low level tag function, takes two arguments: tagspec and content
         content can be a list or an atom"
         (let content (listify content)
           (tostring (eval `(tag ,tagspec (pr ,@content))))))

    (def element (tagspec . content)
         "Simple element, just a convenience wrapper around btag"
         (btag tagspec content))

    ; alias
    (= e element)

    (def section content
         (btag 'div content))

    (def inline content
         (btag 'span content))

    (prn (element 'div "Hello"))
    (prn (element 'div "Hello " "World"))
    (prn (element 'div "Hello" (element 'span "World")))

    (prn (section "Hello" (inline "World")))

    (def vstack args
         "Stack things vertically"
         (string:map section args))

    (def hstack args
         "Stack things horizontally"
         (btag '(table cellspacing 0 cellpadding 0)
            (btag 'tr
               (map [btag 'td _] args))))

    (prn "Testing vstack and hstack")
    (prn (hstack "hstack" (section "hello") (inline "world")))
    (prn (vstack "vstack" (section "hello") (inline "world")))

    (def kls (classes . content)
         "Generates a div with the classes given in 'classes'"
         (let classes (string:intersperse " " (listify classes))
         (btag `(div class ,classes) content)))

    (prn (kls 'big "Hello " "world"))
    (prn (kls '(small big) "Hello " "world"))

-----

2 points by evanrmurphy 5377 days ago | link | parent | on: Omega, or combining lisp and haskell

Just a nit: I'm pretty sure akkartik didn't write the article (he's one of the commenters), but your use of the second person here makes it sound like you're addressing him as the author.

-----

1 point by rocketnia 5377 days ago | link

My mistake. I did think akkartik was the author. XD

-----

1 point by evanrmurphy 5377 days ago | link

You should copy your comment to the article's thread or link back to here. Would be a shame if the OP missed out on your thoughtful response.

-----

2 points by Inaimathi 5376 days ago | link

I found it; better late than never, I guess.

This is a much more thoughtful response than I was expecting, and I've linked it from the original blog post.

-----

1 point by rocketnia 5375 days ago | link

Oh, sorry! I was working on a more focused and less personalized-for-someone-else version of the response yesterday, but it takes me a while sometimes to get to things. XD Glad you found it!

-----

1 point by evanrmurphy 5379 days ago | link | parent | on: Tips on implementing arc

> implementing a continuation passing style interpreter is the way to go if you want first-class continuations and tail call elimination.

I'm intrigued. Is this how most languages get tail call elimination?

-----

3 points by fallintothis 5379 days ago | link

Is this how most languages get tail call elimination?

Well, more languages do TCO than use CPS -- never mind a CPS interpreter. Though CPS is functionally equivalent to the more popular SSA (Static Single Assignment) form, it remains relatively unused; see http://lambda-the-ultimate.org/node/3467. I imagine the comment about using an interpreter is rooted in http://billhails.net/Book/v10.html, a great chapter from a book that goes through writing a Scheme-like interpreter in Perl, including a CPS transform and TCO using a trampoline. (For quick info about what those mean, there's of course http://en.wikipedia.org/wiki/Continuation-passing_style and http://en.wikipedia.org/wiki/Tail_call)

In fact, CPS benefits from TCO. By converting a program into explicit CPS, every function call becomes a tail call (to the current continuation); without TCO, stack space would run out quickly. Certain TCO implementations can also use CPS; see http://en.wikipedia.org/wiki/Tail_call#Implementation_method....

A great discussion about TCO implementation is http://lambda-the-ultimate.org/classic/message1532.html. To get really into it, the master's thesis at http://users.cecs.anu.edu.au/~baueran/thesis/ talks about tail calls in GCC (I've not read it, but it looks interesting).

-----

1 point by evanrmurphy 5378 days ago | link

Wish I could upvote you more than once. Great reply.

-----

1 point by evanrmurphy 5381 days ago | link | parent | on: News.arc for newbies

Customizing news.arc to your liking shouldn't be too challenging if you're willing to program in Arc. Neither should writing your own application similar to news.arc using a web framework for one of those languages, e.g. Ruby on Rails. However, trying to use news.arc and somehow mix it in with your Ruby and PHP code would be a lot trickier, IMO.

Does this help?

-----

1 point by gimondarake 5380 days ago | link

Hello evanmurphy,

First of all, thank you very much for your reply!

To be honest, I am completely new to Arc and news.arc. I thought building a Hacker-News like forum with news.arc would be faster, but maybe I should be focusing on what I know and build with the languages that I actually know. Is it possible to reverse-engineer? news.arc, because I will probably have a bumpy ride to program "ranking algorithm" like the one used in news.arc (Hacker News).

-----

2 points by rocketnia 5379 days ago | link

Hacker News's ranking algorithm isn't public, is it?

At least, it probably isn't in our version of news.arc. As Paul Graham says at http://arclanguage.org/item?id=12468, "I should release a new version though. News.arc is greatly improved since the last release." (I assume the ranking algorithm wouldn't escape scrutiny....)

-----

3 points by kens 5376 days ago | link

I've written up a detailed analysis of the published parts of the news.arc ranking algorithm: http://www.arcfn.com/2009/06/how-does-newsyc-ranking-work.ht...

I noticed that a few pieces of the algorithm were not released, and the algorithm has surely changed since arc3.1, but the published code explains at least the overall behavior of Hacker News ranking.

-----

3 points by evanrmurphy 5382 days ago | link | parent | on: What is Arc?

Hi! Arc is a dialect of lisp. It is influenced by Common Lisp and Scheme [1], two other dialects of lisp, and is actually implemented [2] on top of Racket (a sort of Scheme).

Feel free to ask more questions here. There's also a section of Paul Graham's website with writing about Arc [3], and you can use http://af.searchyc.com/ to search this forum.

Hope this helps!

---

[1] It's also influenced by other programming languages. Python, for example.

[2] I'm speaking here about the original implementation of Arc by Paul Graham and Robert Morris. People on this forum have experimented with porting Arc to other platforms, including Java, Common Lisp, and JavaScript.

[3] http://www.paulgraham.com/arc.html

-----


Nah, we're all simpletons. ;)

Have you used screen though? It's really quite an advanced solution itself IMO.

-----

2 points by SteveMorin 5376 days ago | link

I just started reading up on screen is a awesome solution. I am very surprised that I haven't heard of it before. The only thing don't like about this is that I can't then start the server with a arc equivalent of mysqld_safe which will restart it if it crashes. I would want to be able to have this for a production server. Wonder if it would be possible to scrape a script together that can do that while still dropping you into the repl, and still create a pid file. Any ideas because I usually just launch things like this in the background, which is easy to do.

-----

2 points by aw 5376 days ago | link

I wasn't quite able to tell from your description what is the missing piece for you: is it starting Arc inside of screen at server boot time, or restarting Racket/Mzscheme if it crashes?

I think what you want is for server boot to run screen, which runs a shell script that starts/restarts Arc, which writes its pid out to a pidfile. Does that sound about right? Each step in that process is pretty easy.

-----

1 point by SteveMorin 5383 days ago | link

I haven't used screen to be honest. I was thinking of something more like the swank implementation for lisp

-----

More