However, I honestly don't think this is a useful or general enough function to go in arc.arc, especially as we already have 'fill-table, 'listtab, etc.
As for "creating a named table", er:
(= foo (table)) ; I'm unclear on what's difficult about creating a table.
I think the difficult part is passing in an arbitrary name to a function, for which the tables 'name' becomes set to, but I am just guessing that's what he wants...
and I agree I don't see a whole lot of need for the function to be part of the arc release..., since there are probably better ways to accomplish the same end result.... a good example of which is news.arc's storage of story records.
I think the difficult part is passing in an arbitrary name to a function, for which the tables 'name' becomes set to, but I am just guessing that's what he wants...
I rather doubt that's the issue, as it's easy to do with a macro.
arc> (mac filltbl (tbl keys vals)
`(= ,tbl (fill-table (table) (mappend list ,keys ,vals))))
#3(tagged mac #<procedure: filltbl>)
arc> (filltbl blah '(a b c) '(1 2 3))
#hash((c . 3) (a . 1) (b . 2))
arc> blah
#hash((c . 3) (a . 1) (b . 2))
I think it's just a request for a convenience function to zip together a list of keys with a list of values into a table, since the existing methods for creating tables center around having alternating key/value pairs.
Given a list 'keys of keys and 'vals of vals, this will produce a table of them:
(listtab (map list keys vals))
If you need to update an existing table (which we'll call 'tbl) just use 'each:
(each (k v) (map list keys vals)
(= tbl.k v))
Alternatively:
(map (fn (k v) (= tbl.k v)) keys vals)
All of these solutions rely on the fact that 'map is variadic. It takes any number of lists to map over, and the function is expected to take that number of arguments. For example:
That'll work fine, although the 'do in your function is unnecessary. Also, there is a macro 'or= that does precisely what your first line does (assigns a value to a place if it is nil):
I'm not sure how any of these can work for intializing a table that's not aleady a table...
(= k* '("1" "2" "3"))
(= v* '("One" "Two" "Three"))
assuming t* has not been set - this is what I get:
arc> (filltbl t* k* v*)
Error: "reference to undefined identifier: _t*"
or even:
arc> (filltbl 't* k* v*)
Error: "Can't set reference t* \"1\" \"One\""
so what am I missing ?
filltbl isn't a macro, nor does it affect the global namespace. As written, it just creates a table if its first arg is nil. Of course, this is useless unless it returns that table... oops.
You could push it onto Anarki. Other than that, there isn't much you can do to get it into a public arc.arc. It seems that if a function isn't used in the forum code, pg doesn't include it in the official release.
If you use the latest arc3.tar (unfortunately I haven't gotten around to merging these changes into the arc3.master branch on anarki), 'string will concatenate lists of strings (or indeed anything coercable to string) into one string, with no spaces, recursively:
arc> (string '("foo" bar (2 3) "baz")
"foobar23baz"
Also, 'rem is capable of removing characters from strings.
Arc lists are terminated by 'nil, Scheme lists by '(). Because Scheme lists sometimes appear in Arc, the Arc runtime (such as 'is) treats '() like 'nil.
The only thing that bothers me about this is the same thing that bothers me about 'o for optional arguments: that it messes with destructuring.
arc> (let (o x) '(1 2) x)
2 ;expected result
(1 2) ;actual result
The reason for this is that `(let ,var ,exp ,@body) translates into `((fn (,var) ,@body) ,exp)), and so if var is a list beginning with 'o, it gets interpreted as an optional argument. Likewise:
arc> (let (c d e) '(1 2 3) e)
3 ; current result
Error: "reference to undefined identifier: _e" ; result with argument conversion
There are at least two options here which don't interfere with existing syntax; I'll demonstrate using optional arguments rather than argument conversion for simplicity:
(def foo (x y ('o z)) ...)
This doesn't interfere because binding 'quote is more or less illegitimate in arc. (The reason for this lies in the underlying scheme - if 'quote is lexically bound as an identifier, it doesn't function as a special form.)
(def foo (x y (:o z)) ...)
This doesn't interfere because binding to ':o in arc is more-or-less useless, because ssyntax expands away ':o to 'o. The same is true of '+o.
I personally like the :o, maybe just because it reminds me of CL. Anyway, it shouldn't be too hard to add a special case for ': in ssyntax if it is the first character.
After all, wouldn't that be an error anyway? Therefore redefining it would not interfere with normal usage of ':. In fact, it makes sense to have different versions for each ssyntax if it is at the beginning, end or middle.
well, it is a complicated function. At the very least, it is better than the old version.
That bug must have creeped in because it calls ppr again on the body if it needs to wrap. I'm not 100% sure how to fix it though. Maybe print the first and then map ppr over the rest?
The question is, how to get br-fns to properly indent their bodies. Maybe ppr needs an option to avoid printing the parens.
There's a bug in your updated '+. It uses scheme's 'list? to check whether a given argument is a list to be converted - but 'list? only returns #t on proper lists (those that end with ()), and arc lists end with 'nil. So, for example:
A simple solution is to change the use of list? to pair?, since 'nil and '() are both handled earlier in the cond expression.
Also, having a 'coerce-string function for coercing arguments to '+ to strings and not using it in 'coerce seems odd - if (+ "" x) and (coerce x 'string) behave differently, that's just unintuitive complexity, and if they behave the same, then some common code should be factored out.
"Soon I'll start to put the latest version at arc4.tar"
Wait, does this mean you're planning on releasing arc4.tar soon? Or just that, if you at some point have more changes to make, you'll release them as arc4.tar?