Arc Forumnew | comments | leaders | submit | bOR_'s commentslogin
2 points by bOR_ 6387 days ago | link | parent | on: String to code

Thanks. from this I could figure out the mzscheme version to help my friend out, and for me it hopefully offers me a way for my monkeys to copy behaviour from each other in a way that is still editable (and not just #procedure)

  boris:falcon:~/arc2:rlwrap mzscheme '(+ 5 5)'
  Welcome to MzScheme version 352, Copyright (c) 2004-2006 PLT Scheme Inc.
  > argv
  #1("(+ 5 5)")
  > (vector-ref argv 0)
  "(+ 5 5)"
  > (require (lib "string.ss"))
  > (eval-string i)
  10
  >

-----

3 points by absz 6386 days ago | link

It's probably a better idea to have your monkeys copy code trees around; i.e., rather than having (= monkey1!code "(+ x y)"), have (= monkey1!code (read "(+ x y)")), which is the same as (= monkey1!code '(+ x y)). A scheme like this (if you are careful about what you do with symbols) is a better idea because it's more Lisplike and you can thus take advantage of Lisp's strengths (list manipulation and code-is-data).

-----

1 point by bOR_ 6393 days ago | link | parent | on: Local Scopes?

Isnt' the massive use of global variables not something that is only for newbies?, and from which you learn what is bad about it by experience?

in which case it is no longer a problem for most of us ;)

-----

1 point by bOR_ 6394 days ago | link | parent | on: (delist somelist)

If I read it right, it is a function that for example, can grab the nth entry from a cell (or nth row / column from a matrix)?

You have the code out there somewhere? It is probably good to have some more examples of Arc out in the open, and there'll be things in it I can learn from.

-----

1 point by Darmani 6393 days ago | link

Sorry, I misunderstood your query last night.I just realized the function actually doesn't apply in this specific instance here.

It's a version of the normal map generalized to n-dimensional lists; I forgot when writing it that normal map accepts multiple lists.

However, with that added, it would be useful if you, say, had (((1 2) (3 4)) ((5 6) (7 8))) and wanted ((6 8) (10 12)); that would end up being (apply muldim-map 2 + (list (list (list 1 2) (list 3 4)) (list (list 5 6) (list 7 8))))

(I was going to download Arc's source code and use the source of the original map as a guide to writing a version of muldim-map that could handle multiple multi-dimensional lists on the spot, but I don't believe these high school computers have software that can handle tarballs.)

-----

2 points by Darmani 6393 days ago | link

However, I just realized I had another function in that library that could perform the task you described, although it would be overkill. It's called something like move-muldim-block; it takes a multi-dimensional list and returns a new multi-dimensional list with a multi-dimensional piece of that list moved elsewhere, using a combining function to determing the value of the area in which it was moved (I used it in Sokoban to simplify code that would let let me move a crate character onto a storage character and change it to the crate-on-storate character).

In other words, if lst is set to ((1 2) (3 4)) and f is some function, (move-muldim block (list 1 0) (list 1 2) (list 0 0) +) would be equivalent to (((+ 1 3) (+ 2 4)) ((f 3) (f 4))) (it moves a 1x2 block from coordinates (1 0) to coordinates (0 0)). Just take the car of the result and you have what you're looking for (in which case, we could omit the last argument and use the default value).

For this specific task, apply is a heck of a lot simpler, but I can still post the code if you're interested. I personally found it very interesting to realize that this could be done, and that muldim-move-block is a little more useful than I first thought.

-----

1 point by bOR_ 6393 days ago | link

Hmm. Right now I store the positions of my mobile piec elsewhere than in the world-list. Your function might be handy later on. I haven't yet decided if I want every actor of the world stored in the world (even if some of them might overlap), or store the mobile actors in a separate list.

Right now the thing about sokoban implementations that would interest me most is if you've done anything fancy to generate the output. Having an update of a 2d world scroll by ever so often makes it hard to track movement of a single character through this world. Did you work on that?

-----

3 points by almkglor 6393 days ago | link

Since Arc is a language targeted for the web... have you considered the possibility of generating a web page for it, with maybe next >> and << prev links?

-----

1 point by bOR_ 6393 days ago | link

That might actually work, and just autorefresh the page every second or so :)

First priorities now are finishing the wandering algorithm for the animals so that they're no longer steered but steer themselves, and generalize the code I've some more so that adding more behaviours than just biting things is easy. I'll add the visuals-through webpage idea to that list :)

-----

1 point by Darmani 6393 days ago | link

Sorry, not really. I just used a simple function to print out a 2-dimensional list and resized my terminal window so that the grid would be in the same place after every sequence of moves, which gives the illusion that the same grid is being redrawn.

-----

1 point by Darmani 6393 days ago | link

Small mistake -- the invocation would be (move-muldim block (list 1 0) (list 1 2) (list 0 0) + f) (I hope no-one thought I'd be silly enough to set the function to find the replacement-fn by looking up the global value of f...).

-----

1 point by bOR_ 6394 days ago | link | parent | on: (delist somelist)

Hmm. Seen flat and tried it. in Arc2 flat works recursively, turning (list (list 1 2) (list (1 2)) into (1 2 1 2), which doesn't produce the desired (2 4) when combined with map +

  (map + (flat (list (list 1 2) (list 1 2))))
  (1 2 1 2)

-----

9 points by almkglor 6394 days ago | link

  (apply map + your-expression)

-----

3 points by bOR_ 6394 days ago | link

  (apply map + (map vals:craa!eltm:car (observecone craa!pos (list 0 359) craa!range)))
  (122 31 0)
Thanks! I'll digest what things you can do with the apply map combination in my sleep, but it seems quite handy.

-----

2 points by absz 6394 days ago | link

The apply function takes a function, any number of arguments, and a list, to wit (apply f x0 x1 x2 ... xN args). This is the same as (f x0 x1 x2 ... xN args.0 args.1 args.2 ... args.M). This allows you to construct argument lists at runtime, which can come in very handy.

-----

2 points by jmatt 6394 days ago | link

almkglor nailed it.

That's elegant and simple.

-----

5 points by bOR_ 6397 days ago | link | parent | on: Learning Arc?

Try arc, and if the languages confuses you, step down a bit to a language which is easier but somewhat less powerfull.

To me, that was ruby (I tried lisp about 4 years ago, but found it confusing still, and then went ruby, and now am back in a lisp), which is nearly a written language and might be one of the easiest ways to learn programming.

http://poignantguide.net/ruby/chapter-3.html

As to your question on popularity.. maybe only those people take up lisp (and the odd syntax) if they run into the limitations of less powerful programming languages. Most people might never run into the limitations or realize that they're limited, and keep on using whatever popular computer language they were using.

-----

1 point by bOR_ 6397 days ago | link | parent | on: Implicit progn

nice link, and he makes some good points on keeping away from uberbrevity. Maybe we should let and with rest ;).

-----

1 point by bOR_ 6398 days ago | link | parent | on: let redundant to with?

If there a way in which arc would understand

  (with x 1
     (pr x))
as well as

  (with (x 1 y 2)
     (pr x))
... initially, it would seem that you can distinguish the two by whether there's a ( following the with, but you might get into trouble:

  (let (x y) mylist
     (pr x y)
where let is followed by a (. mmm. I'm a still quite unfamiliar with arc or lisp. Can anyone give an example in which interchanging the "let" for a "with" or visa versa changes the meaning of the function?

-----

4 points by absz 6398 days ago | link

You yourself gave an example. The fact that Arc allows destructuring (that is, writing (let (a b) lst ...)) means that the presence of a list is not an adequate indicator of whether you're letting or withing. And without that, how do you know when you're done defining variables? If you don't parenthesize them, they could go on forever. The only other option is to remove the implicit do in let/with; that way, only the last statement would be run, and the first n would be variable bindings; to run more than one, you would use do.

-----

2 points by bOR_ 6397 days ago | link

Got it :)

  arc> (= b "abba")
  "abba"
  arc> (let (a b) (list 1 2) (pr a b))
  121
  arc> b
  "abba"
  arc> (with (a b) (list 1 2) (pr a b))
  abbaabba"abba"
  arc>

-----

3 points by eds 6397 days ago | link

Yes, you can, but you might have to sacrifice the implicit 'do block in 'let. See http://arclanguage.org/item?id=3234.

That said, it might be good to remove the implicit 'do anyways, since as pg has said, an explicit 'do highlights non-functional code. Combining 'let and 'with would just be a convenient side effect.

P.S. If I am not mistaken I think this would also allow you to do destructuring as well...

-----

3 points by absz 6397 days ago | link

This is actually fairly simple to write (first defining butlast for convenience):

  (def butlast (seq)
    " Returns every element of `seq' but the last one.
      See also [[last]] [[cut]] "
    (cut seq 0 -1))
  
  (mac letn parms
    " Simultaneously ssigns the given (unparenthesized) local variables in the
      one-statement body.
      See also [[let]] [[with]] [[letns]]"
    `(with ,(butlast parms) ,(last parms)))
  
  (mac letns parms
    " Sequentially assigns the given (unparenthesized) local variables in the
      one-statement body.
      See also [[let]] [[with]] [[letn]]"
    `(withs ,(butlast parms) ,(last parms)))
Then letn is like with, but unparenthesized, and letns is like withs, but unparenthesized. (letn = "let n variables".) And yes, destructuring works.

-----

2 points by eds 6397 days ago | link

Perhaps these should be added to Anarki?

-----

1 point by absz 6397 days ago | link

Probably would make sense, but I'd rather wait until we had better names (I don't particularly like these.) Thoughts?

-----

2 points by almkglor 6395 days ago | link

'where ?

  (where foo (some-expression)
         bar (hmm that)
    (some-fn foo bar))

  (wheres val    (another-expression)
          grind  (grr val)
    (that-fn val grind))

-----

3 points by absz 6395 days ago | link

That's not bad... given?

  (given s1 (zebda oualalaradime)
         s2 (cake  symphony in c)
    (play s1 s2))
  
  (givens arc (language-by             pg)
          mzs (implementation-language arc)
    (run-in arc mzs))

-----

3 points by skenney26 6395 days ago | link

Okay, for some reason I can't get this out of my head.

What if "let" becomes "as", given becomes "let", and givens becomes "lets"?

-----

1 point by absz 6395 days ago | link

I would be reluctant to change let, since it's a standard operation in arcN.tar. Otherwise, there's probably some merit to that.

-----

3 points by eds 6395 days ago | link

And now we're back to waiting for pg to do something ;)

-----

1 point by almkglor 6395 days ago | link

Heck no. We can do this ourselves. Remember, the textual transformation to transform let's is just that: a textual translation. It should be possible to create an automated translation tool (based off raymyers' treeparse) that will handle this for us.

Let the old version of 'let be Arc2Let, and the proposed new let be Arc2.7Let. Let the old version of 'with and 'withs be Arc2With and Arc2Withs, respectively. We need to determine if each Arc2Let in the source is composed of a single expression in the body. If it is, we leave it as-is. If it isn't, we simply replace it with Arc2.7As.

For each Arc2With we determine if the body is composed of a single expression. If it is, we replace it with Arc2.7Let, removing the parens around the Arc2With bindings. If it isn't, we leave it as-is. Ditto for Arc2Withs, replacing it with Arc2.7Lets.

We define an expression simply as a sequence of whitespace, base-expression, and whitespace. We define whitespace as being either a comment (either #||# or ;) or ordinary whitespace.

A base-expression is simply a symbol, a number, a character, a string, a quote-expression, a comma and comma-at expression, or a list. A quote-expression is simply the ' quote or ` backquote character followed by maybe whitespace, followed by an expression; comma and comma-at are defined similarly. A list is composed of an opening parenthesis followed by many expressions, followed by a closing parens.

We can determine if a 'let form has several expressions by defining two variants of a 'let form. An Arc2Let is composed of ( <maybe whitespace> let <whitespace> <expression> <expression> <expression> [many <expression>]), and that we have to transform to Arc2.7As (by filtering out the let expression using treeparse 'filt). An Arc2.7LetCompatible is composed of just (let <expression> <expression> <expression>), which we do not transform.

----

Of course, this does represent a veritable fork of the Arc code ^^.

-----

1 point by absz 6394 days ago | link

I would leave with and withs alone, so that we have the option of the implicit do (also because it makes it easier to implement given/Anarki-let :P). And why not use a code-tree-walker if we want to do this—isn't that the point of Lisp?

Still, I don't quite think the fork is worth it….

-----

2 points by almkglor 6394 days ago | link

Actually the point of messing with the existing 'with / 'withs is to force the programmer to consider using the new form of 'let. ^^

The problem of using a code-tree walker is: you lose the comments, which are arguably about 50% the value of the code.

-----

1 point by absz 6394 days ago | link

Right, comments. Just a little important, aren't they? :P

You raise a good point... it's the same number of parentheses either way. But in that case, why not just have let and lets (as given(s)), and be done with it?

-----

3 points by almkglor 6394 days ago | link

> let and lets (as given(s))

Done and on the git ^^

Edit: as an aside, given that pg has said that he'll modify Arc as if there's nobody else programming in it, and that he does not appear to be using Anarki, eventually when Arc3 does come around, it is very possible that Anarki will be incompatible with Arc3. We may very well need to build a converter program in the future to transform Arc2-base Anarki to Arc3-base Anarki, so my abstract nonsense may very well be necessary in the future.

-----

1 point by absz 6393 days ago | link

Thanks!

And general abstract nonsense is almost always a good thing... still, that is worrisome.

-----

1 point by almkglor 6395 days ago | link

'given looks good - I think it's better than 'where.

-----

1 point by almkglor 6397 days ago | link

'these?

  (these x y
         r v
    (foo x r))
Of course it turns into 'theses ....

-----

2 points by skenney26 6396 days ago | link

Interesting idea. I like "as".

-----

2 points by almkglor 6396 days ago | link

  (as var x
      foo 42
    (something var foo))
Hmm...

But how about withs ?? == ass? ^^

-----

1 point by skenney26 6395 days ago | link

Think of it as short for assign :)

-----

1 point by skenney26 6395 days ago | link

How about "as" and "az"?

-----

5 points by absz 6387 days ago | link

I've been programming with given(s) for a little while now, and I really like it. Can't say why I'm so vehement, but it's definitely a Good Thing™. Thank you for bringing this up again (and a "thank you" to aidenn0, if he/she is still reading these fora, for suggesting this in the first place).

-----

3 points by almkglor 6386 days ago | link

An interesting bit about 'givens is that it makes functional programming in an imperative style almost seamless:

  (givens f (car n)
          v f!v
          _ (prn v) ; v isn't being set properly in some cases for some reason...
          l (combinatorics f v)
          _ (prn l) ; debugprint
    (is l 'undef))

-----

2 points by bOR_ 6387 days ago | link

I'm not on anarki, but I've followed this discussion. If you use given rather than let and with, which of the two options below would come out?

arc> (= b "abba") "abba" arc> (let (a b) (list 1 2) (pr a b)) 121 arc> b "abba" arc> (with (a b) (list 1 2) (pr a b)) abbaabba"abba" arc>

-----

2 points by absz 6386 days ago | link

  arc> (given (a b) (list 1 2)
         (pr a b))
  121
The difference between given and let/with is that you cannot have more than one statement in the body of the given. For instance:

  arc> (given (a b) (list 1 2)
         (prn "Here")
         (pr a b))
  Error: "Can't understand fn arg list \"Here\""
What's happening here is that given is trying to bind (prn "Here") to (pr a b), but (naturally) can't bind a string; it takes the first n args, where n is the largest even number less than or equal to the number of arguments provided, and interprets them as variables. You must, therefore, write

  arc> (given (a b) (list 1 2)
         (do
           (prn "Here")
           (pr a b))
  Here
  121
.

Also, I highly recommend switching to Anarki. It's got bugfixes and enhancements galore (and even runs on the newest version of mzscheme).

-----

4 points by bOR_ 6385 days ago | link

So the main drawback of given is that you need to make your do explicit? mmm, I never liked it implicitly anyway ;).

-----

3 points by absz 6385 days ago | link

It's the only "drawback", if such it is. I feel that since you need extra parentheses for either the body or the variables, it's better to wrap the body in a do, since that's less common.

-----

4 points by bOR_ 6398 days ago | link | parent | on: Why Arc is bad for exploratory programming

pg briefly comments / discusses this topic on ycombinator: http://news.ycombinator.com/item?id=190295

  7 points by pg 3 hours ago | link | parent | on: Why Arc 
  is bad for exploratory programming

  Obviously what I meant is that the core language is tuned 
  for exploratory programming.

  Also, I disagree with his criteria. Speed isn't really 
  important for it. And dynamic typing, which he omits, is 
  very important.

-----

4 points by bOR_ 6399 days ago | link | parent | on: Why Arc is bad for exploratory programming

He makes an important distinction in two kinds of exploratory programming, and just sort of is unlucky that he needs the second kind (whereas I'm happy, as I need the first kind)

  I think there are two different kinds of exploratory
  programming. The first I'll call the "Lisp model", where 
  you are building a system from scratch, without external 
  dependencies. The second, which I believe is much more 
  common, is the "Perl/Python model", where you are 
  interacting with existing systems and building on previous 
  work.

-----

2 points by bOR_ 6399 days ago | link | parent | on: type dispatching

tempting reason to switch from arc2 to anarki :).If I understand right, I could make arc understand that if I have a list of lists, (mylist 3 2) wants the second position from the third list.

Nice, is this a something that you can influence locally, within a function, or is it a do-once-per-program thing of arc?

I'll keep it in mind when I'm extending and abstracting my first arc prog at http://bagofsouls.com/images/arc-life.arc :).

-----

2 points by almkglor 6399 days ago | link

Yes, this is possible, although you should note that 'defcall is global (do-once-per-program)

-----

1 point by bOR_ 6399 days ago | link

Is it possible to have it in a local way? (per function / module)

-----

1 point by almkglor 6398 days ago | link

No, or rather not yet.

It might be possible to do so by using some sort of dynamic global (a la kennytilton's implementation some time back, but using 'thread-local objects to handle it).

-----

More