Arc Forumnew | comments | leaders | submit | vrk's commentslogin
3 points by vrk 6448 days ago | link | parent | on: Interface to SQLite in 23 lines of Arc

This make me ask, would it be possible and reasonable to make a rudimentary foreign-function interface using TCP sockets and serializing data to strings, instead of reinventing the FFI wheel again? True, it would be inefficient, but it would not be too difficult to do (say, using YAML [1] as the serialization format), it would give access to many libraries fast, and as a bonus you could run the library service remotely.

Ferrying complex objects with binary data over the link is not going to be pleasant in that scheme, though. And it would be difficult to conceive a generic function call protocol without reinventing RPC or SOAP.

[1] http://www.yaml.org/

-----

5 points by vrk 6448 days ago | link | parent | on: x.y vs y.x

I disagree. x.y should remain (x y). It's plain confusing if you make it look like the dot notation in "object-oriented" languages, when it clearly is not. It's just an alternative way to write function application!

It would make more sense to provide the following kind of implicit currying:

  (def f (x y) ...)
  (let (x 'something)
    (= curried-f f.x))

  curried-f!else ; Calls (f 'something 'else)
Besides, if you switched the arguments or otherwise limited the usefulness of the new syntax to "(obj.f x1 x2)", you could never chain as in "f.obj.x1.x2"; instead, you would need to write "x2.x1.obj.f", which looks ridiculous.

I'm in favour of the dot syntax as infix function application operator. It reminds me of Edsger Dijkstra's reasoning (in fact, he also used the dot as function application). You may want to read [1] for the full story and other nice pondering about infix operators and syntax.

[1] http://www.cs.utexas.edu/~EWD/transcriptions/EWD13xx/EWD1300...

-----

3 points by binx 6448 days ago | link

Then what about "$"? Haskell uses "$" for infix function application operator. Composing objects and methods with "." or "->" is almost a de-facto standard that too many people have got used to...

-----

3 points by vrk 6447 days ago | link

The dot notation is used for at least two different purposes: accessing field values (C structures, for example) and calling methods on/sending messages to an object (Java, for example). Similarly the arrow notation is used for at least two different purposes: accessing field values through a pointer (pointers to C structures, for example) and calling methods on/sending messages to an object (Perl, for example).

Standard? I don't think so. They are used for very different purposes, and just because the convention of separating a record or an object and its attribute with a dot or an arrow is common is not reason enough to blindly adopt the same convention in a new programming language.

Does the dot notation as a record and field separator make sense? Maybe, if that's all you can do in your programming language. Take a look at Common Lisp defstruct for an example of another way to define structures and access fields.

-----

3 points by vrk 6448 days ago | link | parent | on: Comment macro

I would see more value in making a documention generating macro, so that you could easily keep the documentation and program code in one place, not unlike Perl POD and JavaDoc.

  (doc "<function documentation>"
    (def fun args ...))
In normal compilation, the doc macro would simply return the function definition, but it could be defined to generate, say, LaTeX or HTML, or a DOM tree that could be rendered using an arbitrary markup language. The difficulty is identifying the type of code that is enclosed in the doc block, as if you want to extend the paradigm to non-function definitions, or arbitrary macros even, it's going to get hairy.

-----

3 points by treef 6448 days ago | link

already done in the arc-wiki (def fun args "comment" body)

that was like the first thing we added

-----

1 point by vrk 6447 days ago | link

Well! This is certainly a nice improvement.

-----

2 points by vrk 6448 days ago | link | parent | on: Shorter programs, fewer axioms

So point 4 would mean ! is a unary postfix operator, not too different from ~, the unary prefix Boolean negation. You can do this with the current macro system (code not tested):

  (mac ! (f fst . args)
     `(= ,fst (,f ,fst . ,@args)))

  ; Then:
  ((! foo) x . args)
The problem with this is that it's not very efficient. Sure, it's easy to define destructive functions this way from any given function, but for example sorting a list in-place is different from sorting a list, then substituting the value back to the original list. If this were implemented, there would be two different sorts, for instance; insort and sort!, and the latter were always the inefficient one (unless it was defined to be insort, which doesn't make sense in this case).

-----

4 points by im 6448 days ago | link

There are two possible resolutions if the inefficiency is too much to bear:

- Have a really, really smart interpreter that can often convert nondestructive algorithms to efficient in-place ones. This seems difficult.

- Overload foo!. That is, interpret foo! as either foo! itself if it is defined, or (lambda (x . args) (= x (foo s . args))) if it doesn't.

-----

3 points by pg 6448 days ago | link

zap is a lot like this.

-----

1 point by sacado 6448 days ago | link

The other problem is that it changes the global value of fst. It breaks if I want to modify something declared in a "let", for instance.

-----


As a sidenote, square brackets are harder to type on Finnish/Swedish keyboards than ordinary parenthesis. The former requires Alt Gr + {8,9}, the latter Shift + {8,9).

(Why am I using the Finnish keyboard layout to edit code? A bad habit from the past, admittedly.)

-----

1 point by helium 6448 days ago | link

same in germany

-----

3 points by vrk 6453 days ago | link | parent | on: Poll: What would you change in Arc?

You may want to consider something non-traditional in Lisp circles: infix functions. Let me elaborate (and use the proposed new angle bracket syntax).

The "f:g" syntax is a nice idea for function composition, as is "~f" for negation, but the current syntax and semantics seem like a hack. What if we could do this instead:

  (def f (x y) ...)
  (infix f left)

  <x f y>  ; The compiler would transform this to (f x y)
  <x f y f z>  ; And this to (f (f x y) z) (evaluate from the left)

  (infix f right)

  <x f y f z>  ; And now to (f x (f y z)) (evaluate from the right)

  ; Use in "normal" syntax:
  (= foo <x f y>)  ; --> (= foo (f x y))

  ; So, we could do this:
  (infix + right)
  
  (= foo <1 + 2>)  ; Would evaluate/transform to (= foo (+ 1 2))

  (= foo (+ 1 2 3 4))  ; And we could still use the ordinary function call syntax.

  ; Or maybe even:
  (infix + associative)
  (= foo <1 + 2 + 3 + 4>)  ; Transforms to (+ 1 2 3 4) if the function is n-ary, or 
                           ; some arbitrary evaluation order if not.

  ; And now for the interesting bit.
  (def : (f g) (fn (x) (f (g x)))))
  (infix : right)

  (map <f : g> list)  ; What currently is (map f:g list)

  ; Why not extend the idea?
  (def ~ (f) (fn (x) (not (f x))))
  (unary ~)

  (if (<~ predicate> arg) ...)

  ; No, that doesn't have any benefit over ((~ predicate) arg).
Problems:

- How do you define precedence levels? Once you are in this swamp, you can't get out. Maybe all infix functions would have the same precedence to side-step the issue.

- Is it possible to do with only the < > notation? But how would you parse the following without the additional information that + is infix?

  <+ + + + +> 
- Is it worth the two more characters and whitespace?

-----

2 points by vincenz 6453 days ago | link

Precendence levels and such are a known problem and have a known solution. There are rather easy algorithms out there that deal with this. The only problem is that because you lack typing, you could end up with things that are not parsable:

  <x f f y>
  <1 + + 1>
  <1 +>
  <+ 1>
  <+ +>
  <+ ~>
  
Etc...

-----

1 point by vrk 6453 days ago | link | parent | on: How Arc should handle vectors

Are you advocating the style commonly seen in PHP programming?

  $a = array();
  $a[0] = 'foo';
  $a[1] = 'bar';

  /* Fine, $a is an integer-indexed array. */

  $a['another metasyntactic variable'] = 'quux';

  /* Is $a an array (vector) or a hash table? I'm confused. */

  for ($i = 0; $i < 3; $i++) {
     echo $a[$i];
  }

  /* Oops, we looped one too many. No, wait, this prints:
   * foo bar quux
   * Huh?
   */
(PHP automatically assigns as the numerical index the maximum numerical index plus one to the "hash value".)

Hash tables and arrays/vectors are two entirely different concepts. Please do not confuse them with each other.

-----

5 points by dfranke 6453 days ago | link

PHP's brokenness doesn't mean Arc has to imitate it. You'd get a vector up until the $a['another metasyntactic variable'] line, at which point it would turn into a hash table with two integer keys and one string key. Asking for $a[2] would always either return nil or throw an exception regardless of whether it was a hash table or a vector at the time.

-----