Arc Forumnew | comments | leaders | submit | lark's commentslogin
2 points by lark 4412 days ago | link | parent | on: New version of Arc/Nu

Does Arc/Nu support file uploads?

-----

2 points by Pauan 4412 days ago | link

Are you talking about this? http://www.arclanguage.com/item?id=16355

Arc/Nu runs Arc 3.1 unmodified, so it behaves almost identically to vanilla Arc 3.1.

It would probably be possible to add it in, but I don't use the server portion of Arc, so that's out of my league. Patches welcome.

-----

1 point by lark 4412 days ago | link

Yes, that's what I'm talking about.

I use the server portion of Arc to write web-based applications, and would like to upload files.

Anarki hadn't worked very well or very fast when uploading. I might just bite the bullet and use web.py alongside Arc, and have Python calling Arc after a file has been saved. I might also resort to using Anarki, although breaking backward compatibility in a few ways can become a bit of a concern.

I wish there were a language that offered what I need.

-----

1 point by lark 4416 days ago | link | parent | on: How do you http redirect in Arc?

All this redirecting still doesn't get me what I want.

I would like this second link to be what shows up on the top of the browser as the new url. -- but I would also like that page to be initialized with parameters I could express so far only with a closure.

I don't want to pass those parameters to the second link, because then they'll be visible.

So now I need to first save these initialization parameters somewhere (much like saving a closure) and modify the second link to check if there are any scheduled parameters to initialize itself with for a particular user. Some sort of defop-init.

(Am I missing something?)

Down the drain go closures when combined with redirection.

What a hack.

-----

1 point by thaddeus 4416 days ago | link

Why not just pass a session id/key to the second URL* and allow that new page to retrieve the data you don't want exposed?

*or use a hidden field on a form submit.

BTW the limitations you're hitting have nothing to do with Arc or Closures, but rather are just limitations of Browser/HTTP technology (which are by design).

-----

1 point by lark 4416 days ago | link | parent | on: How do you http redirect in Arc?

Great so far. Now... how would you redirect after submitting a form?

  ;; aformh doesn't do it
  (defop prove-it1 req
    (aformh [ (pr "peekaboo") ]
            (pr "do something1 ")
            (submit)
            "/some-fancy-url"))

  ;; Neither does arformh
  (defop prove-it2 req
    (arformh [ (pr "peekaboo") ]
            (pr "do something2 ")
            (submit)
            "/some-fancy-url"))

  (defop some-fancy-url req (pr "Yeii!"))

-----

2 points by lark 4416 days ago | link

The documentation at http://arcfn.com/doc/srv.html reads: "The callback function f must return the redirect target."

The following works:

  (defop arf rq (arform (fn (req) "foo") (prn "Click:") (submit)))
So it is only arform that redirects, not aformh or arformh.

-----

1 point by lark 4416 days ago | link

Well, there is a syntax issue. Using square brackets to express fn fails:

  (defop arf rq (arform [ "foo" ] (prn "Click:") (submit)))

-----

1 point by akkartik 4416 days ago | link

[ ... ] expands to (fn(_) (...))

So [ "foo" ] expands to (fn(_) ("foo")), which fails because you're trying to call a string like a function.

Just use (fn() "foo").

-----

1 point by lark 4416 days ago | link

It might be better if [ "foo" ] expanded to:

  (fn(_) (do "foo"))
rather than

  (fn(_) ("foo"))

EDIT: On second thought, I doubt that's what [ "foo" ] expands to:

[ ... ] expands to (fn(_) (...))

Because you can already write aform submission code that looks like:

  (defop said req
    (aform [ (pr "You entered " (arg _ "foo"))]
      (input "foo") 
     (submit)))
If that's what [ ... ] expands to, aform wouldn't even work so far because it would be trying to call:

  (fn (_) ((pr "You entered.")))
That would be a function call to a function call: (( on the call to pr.

-----

1 point by akkartik 4416 days ago | link

I just ran the following at the repl:

  arc> ([(prn "You entered " _)] 34)
  You entered 34
  Error: "...urces/arc/ac.scm:974:33: arity mismatch;\n the expected number of arguments does not match the given number\n  expected: 1\n  given: 0"
Do you see something different? I think your defop expression is also incorrect. It just happens to have the right side-effect before it runs into the error. You probably have errors at the server -- that aren't visible on the browser.

Edit: I kept having this feeling I'd already pointed this out to you -- and I just found it :) http://arclanguage.org/item?id=16356

-----

1 point by lark 4416 days ago | link

I see the following:

  arc> ([(prn "You entered " _)] 34)
  You entered 34
  Error: "car: expects argument of type <pair>; given ()"
That's good investigation. Note the work described in this thread uses Arc 3.1, not Anarki.

Btw do you mean there's something wrong with defop, or that the example I wrote is incorrect? I had gotten that example from: http://arcfn.com/doc/srv.html

-----

3 points by rocketnia 4416 days ago | link

The examples at arcfn say [do (prn ...) ...] and [w/link (pr ...) ...]. At some point you changed one of these to [ (prn ...)] for your example.

-----

1 point by lark 4414 days ago | link

Thanks. I understand one should write:

  [do (prn "...")]
I support one shouldn't. The do should be implicit.

-----

2 points by Pauan 4414 days ago | link

The reason it does that is so that things like [+ _ 1] work. Under your suggestion, you would have to write [(+ _ 1)] which looks ugly.

Rather than using [(prn ...)] you can just use [prn ...]

---

Incidentally, using Arc/Nu, it's easy to make the square brackets behave the way you want them to:

  (mac square-brackets args
    `(fn (_) (do ,@args)))
I believe Anarki has something similar as well.

-----

1 point by akkartik 4416 days ago | link

I wasn't aware of aformh before, but yes it's not supposed to redirect. But arformh is.

-----

1 point by lark 4422 days ago | link | parent | on: How do you http redirect in Arc?

Thanks, I'll try it.

How would you redirect when executing a closure created with w/link?

-----

2 points by akkartik 4422 days ago | link

There's actually something called w/rlink :)

You might find http://arcfn.com/doc/srv.html useful.

-----

3 points by lark 4419 days ago | link

w/rlink was what I was looking for. Thank you!

-----

1 point by lark 4438 days ago | link | parent | on: How can I store a cookie without a login?

It seems I need something like this:

  (defop-raw some-fancy-url (str req)
    (w/stdout str
              (anon-login req)
              (prn)
              (some-fancy-url-handler req)))

  (def anon-login (req)
       (if (no (get-user req))
           (withs (user (makeid 14)
                        cookie (cook-user user))
                  (= (logins* user) req!ip)
                  (prcookie cookie)
                  (prn)
                  (save-table cookie->user* cookfile*)
                  (user->cookie* user)
                  )))

  (def some-fancy-url-handler (req)
    (pr "Hello World"))

  ;; And visit /some-fancy-url

-----

2 points by thaddeus 4435 days ago | link

If its just a one off thing then you could just emit/print raw JavaScript outputting the document onload function to trigger the storing or updating of your cookie (you could also build arc wrapper functions too).

I.e Document.Onload -> Document.Cookie

-----

2 points by lark 4430 days ago | link

These two lines are not needed:

             (save-table cookie->user* cookfile*)
             (user->cookie* user)
And replace

  makeid
with

  rand-string

-----

1 point by akkartik 4430 days ago | link

Thanks a lot!

-----

1 point by akkartik 4438 days ago | link

Yeah that seems plausible. I guess I don't understand what you're asking.

Perhaps it'll help to tell us more about what you're building and what you're trying to do and why.

-----


It doesn't work for me.

(pr req!ip) keeps showing the IP address of the server rather than the IP address of the client.

I need a way of telling clients apart. Perhaps I should be looking at cookies instead.

-----

1 point by akkartik 4438 days ago | link

To plumb the X-Forwarded-For IP to req!ip, try the patch at http://www.arclanguage.org/item?id=11199. (See gotcha #3 at https://sites.google.com/site/arclanguagewiki/arc-3_1/known-...)

-----

2 points by lark 4434 days ago | link

Thanks. It seems this should work with Anarki.

-----


I would use it.

Could "withs" be renamed to something shorter, like "vars"? Why "progn" and not "do"?

-----

2 points by lark 4566 days ago | link | parent | on: Libraries suck

Can you provide an example of why a library sucks while an abstraction wouldn't?

-----

2 points by akkartik 4566 days ago | link

Yeah, sorry the names have been so useless in penetrating my meaning. I'm planning to write a followup without ever using the words 'abstraction', 'library' or 'service'. Libraries don't have to suck, if you know about how they work. My definition of abstraction was that you had to know something about how it was implemented. It's just that in the real world we don't know how 99% of our libraries work, and our entire eco-system encourages that, and library writers don't care to make their implementations easy to understand because, "Who does that, go read about how it works? Just a couple of guys who'd figure it out anyway, even if I gave them no documentation."

To answer your question, the first example that pops to mind is file uploads in arc. Let's consider a parallel universe where arc came with multi-part file upload support, and it worked for you out of the box, and you never came here with questions, and I never delved into how it worked. In that scenario the file-upload features in arc would be a service to me, not an abstraction. But in this universe all those things happened[1], and now file-upload is an abstraction for me. I know I can get into its guts if I find something wrong. I've become a lion when it comes to file upload (http://paulgraham.com/boss.html).

Notice that this would be true even if the code I wrote for it were identical to the code the authors of arc would have written (ha!). This isn't a technical argument but a social one: Programmers should learn about their dependencies. Or put another way: Ask not if something is an abstraction. Ask if it is an abstraction to you.

(Did that make sense?)

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

-----

2 points by lark 4617 days ago | link | parent | on: Why must Arc have mac?

It's surprising that macros destroy functions rather than generate them.

Thanks for vau. It seems it's defun (and def) that are redundant. Compile-time can be modeled as run-time where t = 0, which means one could have macros at run-time. Some such macros could choose to not evaluate their results.

-----

1 point by Pauan 4616 days ago | link

I don't understand what you mean by macros "destroying" functions. They are completely different concepts. They behave differently and they are used for very different purposes: they are orthogonal.

---

It is possible to design a Lisp that doesn't have a function/macro distinction. Such a Lisp would just use vau for everything. An example is the language Kernel:

http://web.cs.wpi.edu/~jshutt/kernel.html

So, to answer your original question: no, it is not necessary to have both mac and def, but that's how most Lisps (including Arc) do it. I think the primary reason is historical, since I think the speed argument is actually bogus for most programs.

-----

2 points by lark 4615 days ago | link

I meant the biggest casualty of vau (which is the ultimate macro) is def.

-----

1 point by Pauan 4615 days ago | link

Well, I'm not sure I'd say that... what vau does is remove the need for mac, but def is still there, to make it more convenient to define functions.

That does mean that functions can be implemented in user-land, which is very nice, but it doesn't really change functions very much.

---

Also, I prefer to not think of vau as being "the ultimate macro", I prefer to see it as a construct which is very different from macros, but happens to serve the same purpose in most cases, which is why vau can replace macros in most (but not all!) cases.

Then again, I also prefer to see functions as being separate from vaus, even if they're implemented using vau... So take what I say with a grain of salt.

-----

2 points by akkartik 4615 days ago | link

It took me a while to realize that I shouldn't think of vau as a macro-like thing. Macros and functions are different kinds of evaluation policies; vau just lets you construct arbitrary evaluation policies. It's like discovering the quarks that all fundamental particles are made up of; quarks don't preferentially constitute an electron more than a neutron.

The challenge now is to build a runtime where vau can have performance comparable to existing lisp systems.

-----

1 point by Pauan 4615 days ago | link

"It took me a while to realize that I shouldn't think of vau as a macro-like thing."

Welcome to the club. Glad you could join us.

---

"The challenge now is to build a runtime where vau can have performance comparable to existing lisp systems."

Yeah. I think a Lisp without implicit late binding (like Nulan) should have a much easier time at it, though.

-----

1 point by lark 4617 days ago | link | parent | on: Why must Arc have mac?

> The point of functions (def) is to take evaluated arguments as input and spit back a result as output.

That doesn't have to be the point. They could instead take unevaluated arguments and evaluate them only if the user wants them to be evaluated.

-----

1 point by Pauan 4616 days ago | link

That's what vaus do... which I already covered in my second post. The word "function" in Scheme, Common Lisp, JavaScript, Python, Ruby, Lua, etc. all refer to something that always evaluates its arguments. Arc is no different.

-----

More