Arc Forumnew | comments | leaders | submitlogin
2 points by akkartik 5000 days ago | link | parent | on: Wart update: swapped are args to 'isa'

After reading http://arclanguage.org/item?id=4703, I wanted to be able to say both:

  (map f (keep f (sort > ..)))
and:

  (map :over seqs
       (fn (f) ..))
But I can't do that. The ways that wart gets in the way are instructive:

a) First I tried adding an alias to https://github.com/akkartik/wart/blob/2fa2a3b1c0/043list.war...:

  def (map f seq|over)
    ..
But it was easy to forget that I extend map later on: https://github.com/akkartik/wart/blob/2fa2a3b1c0/050list2.wa....

Lesson: when adding param aliases we need to update all later extensions. That seems painful.

b) Even after I identified both places to modify, it's unclear how to deal with this declaration:

  def (map f ... seqs)
I could make it:

  def (map f ... seqs|over)
But then this call combines all args into seqs.

  map :over fs
      (fn (f) ..)
Lesson: rest args by keyword sometimes don't work well. Better to try to find the right names for other args.

Maybe something like this?

  map fs :do (fn (f) ..)
I still can't think of the right keyword to make this readable.

Update: I ended up going with

  map fs :with (fn (f) ..)
(https://github.com/akkartik/wart/commit/537fb6d832)

I also made a change to permit keyword args after rest keyword args:

  map :over fs :with (fn (f) ..)
(https://github.com/akkartik/wart/commit/b3667cda49)

Which of these do people prefer? Any other options?

1 point by akkartik 5001 days ago | link | parent | on: Best way to deploy arc code

It sounds like you have ssh access to your server, in which case it's super easy, no server needed at all, git push will work over ssh.
1 point by idoh 5001 days ago | link | parent | on: Best way to deploy arc code

Thanks Kartik. My git knowledge is about the level where I can pull and push to github and resolve minor conflicts, so this is probably a really basic question -

I know how to install git, but how hard is it to set up a git server to receive the remote pushes from dev?

2 points by akkartik 5001 days ago | link | parent | on: Best way to deploy arc code

Yeah I've been using git with this workflow: http://joemaller.com/990/a-web-focused-git-workflow
2 points by rocketnia 5002 days ago | link | parent | on: Wart update: swapped are args to 'isa'

"I have no idea what I was saying there"

Oh, well I got a lot from it. :) I may have quoted you out of context just now, but I think your post was the first time I thought about the idea that optional args and Haskell-like currying may encourage opposite argument orders. If a function argument is going to remain mostly constant, it should go last so it can be optional, but it should also go first so we can curry it away.

Since then, I've come to think the conundrum is largely internal to currying itself: Currying is useful when people have a frequent need to insert their own locally constant value. That's a tenuous balance in itself, and only one half of it conflicts with the general idea of putting stable values toward the end.

(Here's another really old exchange about argument order in Haskell: http://arclanguage.org/item?id=4705)

At the moment, I just say no to currying. I even manually eta-expand higher-order applications so it's easier to see what function signatures I expect, and so they're easier to step through in a debugger.

  // No:
  _.arrAll( arr, _.isString )
  
  // Yes:
  _.arrAll( arr, function ( x, i ) {  // or just ( x )
      return _.isString( x );
  } )
2 points by rocketnia 5002 days ago | link | parent | on: Wart update: swapped are args to 'isa'

"Hmm, at the very least, perhaps ... (as.int "34")"

I had thought about that for Penknife (http://www.arclanguage.org/item?id=13715). I was going to call it "ify" and then use it with the reverse application syntax:

  [int'ify:arg req s.id]
(Note Penknife's uniform left-associative precedence.)

Similarly, 'isa was going to be "ish":

  int'ish.x
However, I still don't see any semantic benefit in associating a coercion function with a type tag. This would have been nothing but a way to shove a bunch of different utilities into one organizational unit, like Java's static methods. And an organization style like this can backfire: If the system is trying to be securable according to the principles of object-capability model, a programmer who passes a whole open-ended bundle of utilities into untrusted code might accidentally expose more privileges than they've bargained for.

---

"though I know you prefer recognizers to types"

I was thinking of bringing that up in response to the OP, but I think I'm mostly on the side of type tags now! I use tables with "type" fields all the time. I like the ability to dump these tables at a REPL, serialize them, use 'iso for deep comparison, or pass them between frames (in JavaScript). This could be a mess if I use more of these features than I plan to support, but "adding" support is as easy as changing my mind. :-p

My old argument for maintaining a dedicated (foo? x) procedure was so that the 'foo? symbol could be namespaced just like any other member of the global scope. But if the type needs to go outside the language runtime and into serialized data or other concurrently executing runtimes (namely, browser frames), then runtime-local tools for namespace management aren't much help.

Fully abstraction-leak-proof namespace management amounts to having a secure notion of which programs have privilege over which namespaces. Cryptography makes it possible to achieve a pragmatic degree of security at the level of serialized data. I've been keeping this in mind as a guideline during my recent module system pursuit.

1 point by akkartik 5002 days ago | link | parent | on: Wart update: swapped are args to 'isa'

Looking elsewhere in that thread, one idea for really-as is explicit currying:

  (as.int.nil.0 (arg req "id"))
..or something.

Hmm, at the very least, perhaps we can curry as so that we no longer need functions like int (though I know you prefer recognizers to types ^_^)

  (as.int "34")
Now wart's uniform left-associative precedence truly comes into its own:

  (as.int+arg req 'id)
1 point by akkartik 5002 days ago | link | parent | on: Wart update: swapped are args to 'isa'

I have no idea what I was saying there, but it took me a couple of years to truly appreciate both your points :)
2 points by rocketnia 5002 days ago | link | parent | on: Wart update: swapped are args to 'isa'

Reminds me of this old thread you and I participated in: http://arclanguage.org/item?id=10752

aw: "Here's an "as" macro, which swaps the arguments to "coerce", and quotes the type:"

me: "You could do the same thing with isa. [...] This particular example probably isn't quite as useful; if I have a complex expression, I usually want to use the result itself at some point, rather than just passing it to isa."

you: "Languages like haskell do a better job explicitly encouraging this practice - you can curry functions with frequently-used args."

1 point by akkartik 5003 days ago | link | parent | on: Wrong comments time

Ah, you were right. Now fixed: https://github.com/nex3/arc/commit/ef519e72dd. Thanks a lot for catching this.
2 points by akkartik 5003 days ago | link | parent | on: Wrong comments time

This is now fixed (as of https://github.com/nex3/arc/tree/3d643ea924). I ended up backing off on changing defaults; arc now goes back to providing no support for them whatsoever. It's too hard to track default values while we wrap exprs in functions.

It's also been a constant enough question in my mind how the current semantics differ from arc3.1 that I wrote up a report.

Arc3.1: https://github.com/nex3/arc/blob/3d643ea924/lib/tem-report.a...

Current: https://github.com/nex3/arc/blob/3d643ea924/lib/tem-report.c...

1 point by rocketnia 5005 days ago | link | parent | on: Cyclical data structures in arcueid

"the rabbit and the hare"

Whoops. I didn't mean that. XD

2 points by rocketnia 5005 days ago | link | parent | on: Cyclical data structures in arcueid

Here's a slightly different bug I found before your update. It's another case where I don't know what behavior you expect, but it probably isn't this. :-p

  (do (a <- '(1 2 3)) (lastcdr.a <- cdr.a) nil)
  => nil
  (do (b <- '(1 2 3 2 3)) (lastcdr.b <- cdr.b) nil)
  => nil
  (not+not+iso a b)
  => nil
  (not+not+iso b a)
  => 1
(I'm using not+not+iso so it returns a predictable value rather than an address.)
1 point by akkartik 5005 days ago | link | parent | on: Cyclical data structures in arcueid

Yeah I tried it out before posting. I had to take pains in iso to make sure we do one full traversal. With print I didn't care as much.

Update: Ack, I found a bug in iso (http://arclanguage.org/item?id=17365):

  x <- '(1 2 3)
  y <- '(1 2 4)
  (do1 nil (<- lastcdr.x x lastcdr.y y))  # Avoid printing the cycles
  (iso x y)   # not nil!
2 points by rocketnia 5005 days ago | link | parent | on: Cyclical data structures in arcueid

  You posted:
  
  x <- '(1 2 3)
  lastcdr.x <- cdr.x   # 1 2 3 2 3 2 3 ...
  print x
  1
  2
  ...
Is that the behavior you expect? I would expect "1 2 3 ...", but it looks like the rabbit and the hare meet at the (3 ...) cons and stop.

  1 2 3 2 3 2 3
  *              Print "1".
    * *          Print "2".
      *   *      Print "...".
1 point by akkartik 5005 days ago | link | parent | on: Wrong comments time

Perhaps that's because you have nothing saved yet? It shows stories submitted by others that you've upvoted.
1 point by Fenng 5005 days ago | link | parent | on: Wrong comments time

OK.

I found another BUG, when click 'Saved' link in profile page, it's a blank page.

1 point by akkartik 5005 days ago | link | parent | on: Wrong comments time

Sorry, I meant set the email in your 'about' field. The 'email' field is only visible to the admins of the arc forum.
2 points by Fenng 5005 days ago | link | parent | on: Wrong comments time

Thanks a lot! It's work now .

By the way, I've set my email in profile.

1 point by akkartik 5005 days ago | link | parent | on: Cyclical data structures in arcueid

I'm just taking a constant-factor hit :) A few extra iterations doesn't change the result for either print or iso. And for cycles that loop back all the way to the start it turns out there's zero overhead.

  x <- '(1 2 3)
  lastcdr.x <- x  # 1 2 3 1 2 3 1 ...
  print x
  1
  2
  3
  ...  # exactly one iteration
But:

  x <- '(1 2 3)
  lastcdr.x <- cdr.x   # 1 2 3 2 3 2 3 ...
  print x
  1
  2
  ...
2 points by rocketnia 5005 days ago | link | parent | on: Cyclical data structures in arcueid

"The key difficulty is that there's two dimensions, so does the number of hares double each iteration?"

Hmm. As the tortoise goes down branches, its location becomes indeterminate. As the hare goes down branches, its location becomes indeterminate relative to the tortoise, so we might need multiple hare markers per branch if we're doing a tortoise-directed search. If we try using the hare to direct the search instead, then we may still need to keep a growing history of hare locations on each branch so the tortoise can follow.

Either way, keeping a hash table sounds more straightforward to me.

Are you using this algorithm properly? I haven't seen any of your example code do a second pass to find out where the cycle begins and what its period is. But maybe you don't need to...?

1 point by akkartik 5005 days ago | link | parent | on: Wrong comments time

Ok, there's now a temporary workaround up: https://github.com/nex3/arc/commit/4492309637. Do a git pull.

This is harder than I thought. Things will likely change as I continue to work on this, so that templates written to disk now might not be quite what you get back after a git pull in future. If you put your email in the about section of your profile I'll notify you when that happens, and exactly what changed.

1 point by Pauan 5006 days ago | link | parent | on: Cyclical data structures in arcueid

Wikipedia has more algorithms for cycle detection:

https://en.wikipedia.org/wiki/Cycle_detection#Brent.27s_algo...

2 points by dido 5006 days ago | link | parent | on: Cyclical data structures in arcueid

Well, now that I consider it the real reason why I missed these cycle detection algorithms is that I've never thought of conses as being just lists. Sure, they're general enough to represent lists, and binary trees, but with the presence of scar and scdr, they are also capable of representing directed graphs with vertices of at most degree 2. In general, any Arc variable can be considered as a reference to a general directed graph (hash tables in particular can be considered vertices of arbitrary degree). Thus, pretty-printing an Arc variable boils down to traversing the graph it represents, and the traversal order that seems like it makes best sense here is depth-first search.

To do the #0=(#0# . 2) notation though seems like the traversal needs to be done twice, first to get the numeric assignments, and next to actually print them. Not sure if it can be done in one pass without making a tree of prettyprint fragments. A marshalling algorithm will need to do it that way though, I should think.

2 points by Fenng 5006 days ago | link | parent | on: Wrong comments time

Waiting for you ...

:)

1 point by akkartik 5006 days ago | link | parent | on: Cyclical data structures in arcueid

As it happens I provided an implementation of iso at http://arclanguage.org/item?id=17365 :) Let me know if my toy language isn't clear. The basic idea is that you need two hare pointers, one for each arg.
2 points by dido 5006 days ago | link | parent | on: Cyclical data structures in arcueid

Removing mutating cons cells would only solve part of the problem. One would also need to essentially eliminate hash tables, and practically all mutating state. And no, I never understood how monads worked. XD

And yes, the ultimate goal I have for Arcueid is to make a fully compatible Arc implementation, so breaking this sort of compatibility is out of the question as far as this project is concerned, but it is interesting to consider.

It would, for one, make real-time garbage collection a lot simpler...

2 points by dido 5006 days ago | link | parent | on: Cyclical data structures in arcueid

Interesting. I'd been looking around for cycle detection algorithms and knew I might have forgotten a simpler algorithm. I think that would do very nicely for the pretty printer and most likely the marshalling algorithm as well. We'll see if I can find a way to adapt it to work for iso as well, though on the face of it, it doesn't look that straightforward.
2 points by akkartik 5006 days ago | link | parent | on: Wrong comments time

Ah, thanks for the report! That was my fault. This bug has been in anarki for over a year, ever since I messed with its templates: http://arclanguage.org/item?id=15664. In particular this highlights an issue with change a) at http://arclanguage.org/item?id=15690: when the default value is an expression like (seconds) for the time field, it's pointless not to inline it.

Stay tuned; I'll fix this in an hour or three.

2 points by Pauan 5007 days ago | link | parent | on: Cyclical data structures in arcueid

"Oh, you mean dido."

Yes, my post was directed at dido.

---

"It's a good question whether you ever need cycles outside of these two scenarios."

I suppose there might be some algorithms that work better with mutable conses, but honestly, I think conses work best when they're functional, since they have a recursive definition. Making them mutable muddles a lot of different things with no real gain because you rarely mutate conses in Arc.

More