Arc Forumnew | comments | leaders | submit | evanrmurphy's commentslogin
2 points by evanrmurphy 5436 days ago | link | parent | on: How is join different from +?

Well, besides the obvious difference that '+ works for numbers and strings.

I'm surprised that join doesn't work for strings. The heading "Using + to concatenate sequences is a lose" suggested to me that the alternative (join) would work for all sequences, not just lists.

-----

3 points by rocketnia 5436 days ago | link

That's a good point. However, when a function like 'string concatenates strings like 'join concatenates lists, it's most consistent for (string) to be "", right? You can't have (join) return "" as long as it returns nil, unless you also make nil and "" the same value.

Now, I'd trade bits of consistency for the sake of significant convenience, but I don't think there's significant convenience at stake here. I never use 'join or 'string for concatenation in a place I couldn't use + nil or + "", which are just as convenient. If we did that instead, we'd have a smaller vocabulary with less room for second-guessing the design. So IMO, 'join may well be useless, and the main value of 'string is that, when used with one argument, it plays well with ssyntax and 'map.

-----

2 points by evanrmurphy 5436 days ago | link | parent | on: How is join different from +?

Not entirely sure, but I think they're synonyms. Paul Graham initially liked + for concatenating sequences but later decided he prefers join [1]. Rtm still likes +.

[1] See "Using + to concatenate sequences is a lose" in http://www.paulgraham.com/arclessons.html

-----

3 points by evanrmurphy 5445 days ago | link | parent | on: 1000 Days

The thousand-day language...

Almost 3% of the way to 100 years.

-----

1 point by hasenj 5442 days ago | link

Not even close. The 100 years language is (supposedly) the language people will want to use even in a 100 years from now.

It's not even a 3 years language yet, because well, people are not jumping all over it.

Plus, a 3 year language implies a language with a very short life-span :p

-----

1 point by evanrmurphy 5442 days ago | link

Yes, you're right. (Although the grandfather comment didn't really mean anything. Just silliness.)

-----


I'm glad it's working out for you!

-----


I keep getting surprised by how much setup matters for my own programming satisfaction. Hacking Arc became a great deal less frustrating for me once I was introduced to rlwrap, and then the possibility of an in-editor REPL for emacs using inferior-arc-mode.

-----

2 points by evanrmurphy 5475 days ago | link | parent | on: Ask: html and javascript in arc

but how do I get at the `obj.method` syntax?

  ((jQuery "#content") `hide)
Note that the compiler uses JavaScript bracket syntax rather than dot syntax, so your output will really be:

  jQuery('#content')['hide'];     // same as jQuery('#content').hide();
I walk through "hello world" in jQuery using Arc->JavaScript at http://arclanguage.org/item?id=12141 if you're interested.

In your experience, is writing javascript as arc a feasible idea? or even a good one?

It is feasible, but there are tradeoffs. If you generate your scripts and markup in Arc, you get the benefit of having more of your code in uniform syntax, and it's often more concise. However, your system will be more dependent on Arc, such that if you decide to port to another language, it will be more work. You also give up a lot of the handy editor tools designed to help you write JavaScript/HTML/CSS by hand.

jQuery already takes so much of the verbosity out of writing JavaScript that it can feel a bit excessive to try and metaprogram it away any further.

Recently I've been experimenting with a lot of different server-side languages and frameworks, so I have incentive to keep my scripts in their rawer but more portable form.

-----

2 points by hasenj 5473 days ago | link

> jQuery('#content')['hide']; // same as jQuery('#content').hide();

Not really the same, it's missing the () from the end to call the function.

Adding another level of parens seems to do the trick:

    (((jQuery "#content") `hide))
results in:

    jQuery('#content')['hide']();
But that style doesn't seem like something I'd want to do.

> jQuery already takes so much of the verbosity out of writing JavaScript that it can feel a bit excessive to try and metaprogram it away any further.

Agreed.

There are still annoyances though, like the anonymous function syntax when combined with function calls and json literals:

    jQuery(".item").each(function(){
              fn_that_takes_json({ id: $(this).id, obj: $(this) }); });
Too messy, and too many places to go wrong: brace in the wrong place, missing comma, missing semi colon, etc.

-----

1 point by evanrmurphy 5473 days ago | link

it's missing the () from the end to call the function.

You're right, thanks for catching that.

The `#` in that jQuery selector condemns the Arc version to look worse than the code it's attempting to repair. If the selector didn't have special characters, as in

  jQuery('content').hide();
then you could exploit Arc ssyntax and do

  (jQuery!content.`hide)
but I won't pretend like that's a great improvement either.

-----

1 point by hasenj 5472 days ago | link

perhaps a js macro could allow a better syntax?

I don't know if macros can do this,

    (js
        (jQuery "#content"
            (toggle))        ;; translates to: jQuery("#content").toggle();
        (jQuery ".cue"
            (html "done")
            (addClass "t"))) ;; translates to: jQuery(".cue").html("done").addClass("t");

-----

2 points by rocketnia 5472 days ago | link

Here's the start of an approach loosely influenced by that:

  (def jquery-dedot (symbol)
    (when (isa symbol 'sym)
      (zap string symbol)
      (when (begins symbol ".")
        (cut symbol 1))))
  
  (def parse-chain (chain)
    (whenlet (first-method-sym . rest) chain
      (iflet first-method jquery-dedot.first-method-sym
        (let numargs (or (pos jquery-dedot rest) len.rest)
          (let (first-args rest) (split rest numargs)
            (cons (cons first-method first-args) parse-chain.rest)))
        (err:+ "A chain given to 'parse-chain didn't start with a "
               "dot-prefixed method name."))))
  
  (mac jquery (selector . chain)
    (let result `(js-call js-var!jQuery ,selector)
      (each message parse-chain.chain
        (zap [do `(js-send ,_ ,@message)] result))
      result))
  
  (def js-var (name)
    (annotate 'rendered-js
      string.name))
  
  (def js-call (callee . args)
    (annotate 'rendered-js
      (+ "(" tojs.callee "(" (intersperse "," (map tojs args)) "))")))
  
  (def js-send (object method . args)
    (annotate 'rendered-js
      (+ "(" tojs.object "[" tojs.method "]("
         (intersperse "," (map tojs args)) "))")))
  
  (def tojs (value)
    (caselet type-value type.value
      rendered-js  rep.value
      int          string.value
      string       (do (zap [subst "\\\\" "\\" _] value)
                       (zap [subst "\\'" "'" _] value)
                       (zap [subst "<'+'/" "</" _] value)
                       (zap [subst "]]'+'>" "]]>" _] value)
                       (zap [+ "('" _ "')"] value)
                       (tostring:w/instring stream value
                         (whilet char readc.stream
                           (let code int.char
                             (if (<= 32 code 127)
                               pr.char
                               (let hex (coerce code 'string 16)
                                 (pr "\\u")
                                 (repeat (- 4 len.hex) (pr #\0))
                                 pr.hex))))))
        (err:+ "A value of type \"" type-value "\" can't be "
               "translated by 'tojs (yet).")))
In action:

  arc> (jquery "#content" .toggle)
  #(tagged rendered-js "((jQuery(('#content')))[('toggle')]())")
  arc> (jquery ".cue" .html "done" .addClass "t")
  #(tagged rendered-js "(((jQuery(('.cue')))[('html')](('done')))[('addClass')](('t')))")
This code isn't necessarily shorter than the JavaScript code, but it's set up so that you can conveniently compute parameters from the Arc side via things like (jquery "#blah" .height (- full-height top-height)) while also being able to compute them naturally from the JavaScript side via things like (jquery "#nav" .height (jquery "#content" .height)).

One downside is all the parentheses this leaves. But if that turns out to be a problem, the thing I'd do is to rewrite the JavaScript-generating utilities to return meaningful AST objects rather than just tagged strings. That way, the AST can be pretty-printed in a separate step, once the context of each and every JavaScript expression is known.

An AST could also be good for displaying as debug output, minifying, verifying, compiling, translating to multiple programming languages, and doing any other kind of inspection. The format of the AST could also be set up to make it easier for different generated parts to avoid tripping over each other; for instance, there could be scopes for element IDs or a library dependency resolver.

I just finished converting my website's static site generator to Arc and Penknife (a language I've been making), and I'm using this kind of AST approach, if only 'cause HTML ASTs are so simple. :-p I haven't had the need to generate JavaScript or PHP yet--and I don't even use any PHP right now, lol--but I expect to get around to that someday, and at that point things'll get kinda interesting.

-----

1 point by evanrmurphy 5478 days ago | link | parent | on: Local recursive functions

Hi guynoir. (Garrison Keillor fan? :) Maybe you're looking for rfn, which is defined as follows in arc.arc:

  (mac rfn (name parms . body)
    `(let ,name nil
       (assign ,name (fn ,parms ,@body))))
Here's a trivial example:

  ; prints 1..10, each on its own line

  ((rfn foo (x)
    (prn x)
    (if (>= x 10)
         nil
        (foo (+ x 1))))
  1)
Hope this helps.

-----

1 point by evanrmurphy 5483 days ago | link | parent | on: I am newbie on programming

Welcome to Arc and the programming world in general! :)

There's http://tryarc.org/ if you want to try Arc but are having trouble installing it. Consider using that to go through the Arc tutorial (http://ycombinator.com/arc/tut.txt) and otherwise experiment with the language until things are set up on your system. (Full disclosure: I created the site.)

-----


If you're frustrated with the installation but really want to try out Arc, http://tryarc.org/ provides a functional Arc REPL in your web browser. You could use it to go through the Arc tutorial [1] and otherwise experiment with the language until things are set up on your system. (Full disclosure: I created the site.)

You were probably following the brief installation instructions at [2], which tell you to download Arc 3.0. If you download Arc 3.1 instead (see [3]), then you have more flexibility about which version of mzscheme to use. In any case, once you have installed mzscheme and downloaded/untarred arc3.[0|1].tar, you cd into the arc3.[0|1]/ directory (where as.scm resides) and run "mzscheme -m -f as.scm" to launch an instance of the Arc REPL.

To be sure, which operating system are you running?

---

[1] http://ycombinator.com/arc/tut.txt

[2] http://arclanguage.org/install

[3] http://arclanguage.org/item?id=10254

-----

2 points by Andrew_Quentin 5485 days ago | link

Windows XP

I did try the site for a bit, its quite cool. Was trying to learn some schema earlier on, but totally lost as to how to get arc to launch.

By cd, do you mean the windows command prompt? Haven't used that before. Tried to though, but it says that neither run nor mzscheme are recognised commands.

-----

2 points by evanrmurphy 5485 days ago | link

Windows XP

Well I'm glad I asked because the above instructions presume you're on a Unix-based system (Linux, Mac OS X) working from the command line.

Unfortunately, I'm not familiar with how to get Arc installed on Windows. Here's one guide on the topic [1], but I can't vouch for its accuracy. If you want to find more related resources, try using http://af.searchyc.com/ to search this forum for posts that mention "Windows".

By cd, do you mean the windows command prompt?

Yes. cd is a standard command on shells for both Windows and Unix to change the current directory.

---

[1] https://dev.youdevise.com/YDBlog/index.php?title=installing_...

-----

4 points by rocketnia 5485 days ago | link

I use Arc on Windows XP. My Arc 3.1 setup process is pretty straightforward:

1) Get Racket. http://racket-lang.org/

2) Get Arc. http://arclanguage.org/item?id=10254

3) Make a batch file that'll run an Arc REPL for me when I double-click it. Here's my batch file, with a boatload of comments to help you figure out what I'm doing: http://gist.github.com/576688 There's probably some room for improvement, but it's what I'm happily using at the moment. (Note that it crashes a bit if you close the terminal window while Racket 5.0.1 is running, instead of exiting via a Racket (exit) call or an Arc (quit) call. I think this is a Racket issue, since previous versions don't crash that way.)

4) Make some necessary changes to Arc so that it stops giving errors on Windows. There are two main issues here. For Arc to start at all, you'll need to fix 'setuid (http://arclanguage.org/item?id=10625). Then, if you also want to run web applications, you'll probably need to fix the system call to mkdir (http://arclanguage.org/item?id=4652), and I wouldn't be surprised if one of the other system calls breaks too.

If you've already installed Cygwin, the system call issues may not exist, but I'm not totally sure of that. I know I only encountered the mkdir issue on a Cygwin-free Windows computer after having used Arc on a Cygwin-ful Windows computer for quite a while... but I'm not sure I've ever actually tried to run Arc web applications on the Cygwin-ful computer.

-----

3 points by waterhouse 5485 days ago | link

Tip: At least for me (on a Mac), running Arc with "[racket|mzscheme] -f as.scm" and then hitting ctrl-C at some point will kill the whole process, instead of dropping to a [Racket|Scheme] prompt from which I can use (tl) to return to the arc> prompt. Replacing the command with "[racket|mzscheme] -i -f as.scm", -i for interactive, fixes this. Much better.

Also, I highly recommend rlwrap. See this thread: http://arclanguage.org/item?id=10

I have added the following to my .bash_profile (probably the Mac equivalent of .bashrc):

  export PATH=/Applications/Racket\ v5.0/bin:$PATH
  alias arc='rlwrap -c -r -l ~/Documents/ARC_LOG -q "\"" -C arc racket -i -f ~/Dropbox/arc3.1/as.scm'
I used to have 'cd ~/Dropbox/arc3.1;' before the 'rlwrap ...' part; the aload function and all the Arc files that load other Arc files (libs.arc) assume that you're in the Arc directory. I worked around this by wrapping all the calls to 'aload in as.scm like this:

  (parameterize ((current-directory (current-load-relative-directory)))
    (aload "arc.arc")
    (aload "libs.arc") 
    
    (aload "sh.arc")) ;my stuff
Now I can call "arc" from any directory; it will load fine and I'll still end up in the directory I started in.

-----

1 point by evanrmurphy 5485 days ago | link

rlwrap really is great. I like it almost as well as having my REPL in Emacs.

Also, that's a neat idea to house your Arc installation in Dropbox.

-----

1 point by Andrew_Quentin 5485 days ago | link

Wow, that's much more complex than I though. I'm glad I asked. No wonder I was lost.

Thanks a lot. I'll try and follow those instructions and see if it works.

-----

1 point by evanrmurphy 5485 days ago | link

Good luck and let us know what happens!

-----

1 point by Andrew_Quentin 5485 days ago | link

Its Alive!

Trying to figure out the dev\urandom problem now

but thanks man!

-----

1 point by evanrmurphy 5485 days ago | link

Great, happy hacking! :)

-----

1 point by evanrmurphy 5493 days ago | link | parent | on: Pliant -- Lisp and C merge

The basic idea is to do all computation on the server and treat the web-browser as a graphical dumb terminal. All javascript event handling code is moved to the server, without sacrificing usability.

What's the motivation for this? I'd say that the given addition example definitely sacrifices some usability because it takes so much longer to evaluate than if you had computed it in the browser. It also seems like this would make your web apps less scalable, since even the most trivial client-side scripts would consume server resources on a per-user basis. (And how would you do something like a JavaScript animation using this model?)

Sorry if this sounds hyper-criticial. I'm interested in better understanding what makes Pliant unique. (Much of your website reads like an advertisement though, which makes this difficult.)

-----

2 points by jazzanova 5493 days ago | link

The web front-end is just one of the libraries and it has its drawbacks.

The actual language can do whatever. The language docs are here:

http://hc.fullpliant.org

What makes it unique than most langages is meta-functions (macros) and compilation down to machine code.

-----

More