Re: comments on my design of a new language?




<ryanlowe0@xxxxxxxxx> wrote in message
news:1137095318.179089.264750@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Typing is likewise kept simple. All the expected numeric types will
> exist, plus strings and the function type, and that is it. I am not
> planning on allowing user-defined types. I suspect many will dislike
> this aspect, but it has numerous advantages, which I will refrain from
> citing here.

Maybe we're getting into semantics here, but it seems to me you actually
have a couple other types. You have a "dictionary" type, which can be
indexed by a string or a regular expression, and is unordered. You have a
"list" type which has no direct indexing facility, but which is ordered. You
also have a regular expression type.

Occasionally, you seem to treat a list of length one, and a primitive scalar
value, as being indistinguishable. Other times, they are treated very
differently.

[snip]
>
> Data is arranged in tree structures of strings sort of like nested
> dictionaries, that terminate with literals, or (possibly
> multidimensional) arrays of literals (basic types). Nodes can be
> accessed with dot syntax if they are named according to standard
> variable naming conventions, otherwise they must use braces.
>
> animals.platypus # dot syntax
> animals{'three-toed sloth'} # string interpretation
> b = 'badger'
> animals{b} # variable interpretation
>
> animals{['pig', 'cow']} = # multiple value getting and setting
> 'swine', 'bovine'
> print animals.pig # -> 'swine'
>
> Regular Expressions can also be used for looking up nodes or searching
> terminal strings with a dedicated <angle> bracket syntax. Yes,
> less-then < must have whitespace in front of it and patterns may not.
>
> animals<pig|cow> = 'swine', 'bovine'
>
> animals<mo[a-z]*> # -> animals{'mouse', 'moose', 'monkey'}
> animals<.*og> # -> animals{'frog', 'dog', 'hog'}
> s = 'regexs rock!'
> s<r.> # -> ['re', 'ro'] literal strings
> text<[aeiou];i> = '*' # replacements, flags at end after a ;

What are the rules for when the number of assignment values differ from
the number of receiving values? Since you seem to be allowing for arbitrary
regular expressions for looking up nodes, the programmer may not know how
many nodes will match a particular regexp lookup.

Do you have some sort of facility for programmatically differentiating
between a variable which contains a dictionary, and a variable which
contains a primitive value? Is there a way to get all keys of a dictionary?

>
> Function are first class. Calling is done with the :colon operator. The
> first argument goes in front of the colon, while additional arguments
> are listed in parens after the function name. This mimicks
> method-calling in apperance, but it is strictly procedural.
>
> # (1) procedural style
> # finallydo(thendo(do(x, something()))) # backwards when nesting
>
> # (2) method style
> # x.do(something).thendo().finallydo() # easier to read
>
> # (3) my lang
> x:do(something):thendo:finallydo # looks like (2), works like (1)
>
>
> # to sum up:
> # {interpret}
> # [index]
> # <pattern>
> # :func-call()
>
>
> An exclamation! can be used instead of the usual :. This signals a
> mutable function call, meaning the reciever is modified in place, where
> normally a copy is made. The ! is not part of the function name as in
> Ruby; it is an adverb that can be used in any function call, so long as
> the left-side is not a literal value.
>
> x = [1,2,3,4,5]
> a = x:swap(0,3) # x still [1,2,3,4,5]
> x!swap(0,3) # x now [4,2,3,1,5]

When "a copy is made", is it a deep copy, making a copy of the entire tree
that a variable may be the root off, or a shallow copy, creating a single
new dictionary, but otherwise each child of that dictionary now has an
additional reference to them?

Can a dictionary contain a reference to itself as one of its values? Can you
compare too dictionaries for equality? If so, are they equal by value, or by
reference?

Consider the statement:

x!do(something)!thendo!finallydo

Presumably what happens is that do() is called on x and something, and
returns some value. Whatever this value is, it is assigned to x. Then,
thendo() is called, and again it returns some value, this value being
assigned to x, and so on. So far, so good.

What about this statement?

x!do(something):thendo!finallydo

do() modifies x, and then a copy of x is made, upon which thendo() is
called. Is the copy made before do() modifies x, or after do() modifies x?
Either way, the copy is then modified by finallydo(), but this copy isn't
stored anywhere, so the changes are lost. So let's save the result
somewhere. Presumably, the syntax is something like:

a = x!do(something):thendo!finallydo

So here, I'm guessing x is modified by do(), and a copy of x is created, and
thendo() operates on this copy. Then, finallydo() modifies the copy, and the
copy is store in a. What about the following?

a = x!do1():do2()!do3():do4()!do5()

Here, do1() modifies x, do2() acts on a copy of x, and that copy gets stored
into a. do3() then modifies the copy. do4() then makes a copy of that copy.
do5() then modifies the copy of the copy, but the value is lost, because it
doesn't get stored anywhere.

>
> # ! can be used to modify operators as well
> x = 1
> x !+ 2 # x == 3
>
> Now for the big guns! Automatic implicit iteration. Array libraries
> like Python's numarray display this behavior on arrays, but I make it
> standard. It even works for arbitrary function calls!
>
> x, y, z = 0 # multiple assignment
> v = [1,2]
> v = [3,4] - v # -> [2,2] element-wise
> v !+ 3 # -> [5,6] singles distribute
> [2,3] + [1,2,3] # error - dimension mismatch
> v ++ [1,2,3] # -> [1,3,1,2,3] appending
> [[1,2],[3,4]] + 1 # -> [[2,3], [4,5]]
> [[1,2],[3,4]] + [1,3] # -> [[2,5], [4,7]] multi-dim
> [[1,2],[3,4]] + v # dimension mismatch error

I'm not sure that these rules are consistent. It seems like you have two
types of values here: scalars, and lists. If you add a list to a list, the
length of each list has to be the same, and each element from the two list
are added together pair wise. If you add a list to a scalar, then the scalar
is added to each element in the list.

[3, 4] - [1, 2] = [3 - 1, 4 - 2] = [2,2]

[2, 3] + 3 = [2 + 3, 3 + 3] = [5,6]

[2, 3] + [1, 2, 3] is not defined

[[1, 2], [3, 4]] + 1 = [[1, 2] + 1, [3, 4] + 1] = [[1 + 1, 2 + 1], [3 + 1, 4
+ 1]] = [[2, 3], [4, 5]]

So far, this is fine, and everything matches your examples above.

[[1, 2], [3, 4]] + [1, 3] = [[1, 2] + 1, [3, 4] + 3] = [[1 + 1, 2 + 1], [3 +
3, 4 + 3]] = [[2, 3], [6, 7]]

This last one doesn't match your example, which says that the result should
be [[2,5],[4,7]].

>
> Functions are made to exhibit the same parallel and distributive
> properties as shown with arrays. To achieve this, we must require that
> array arguments declare their dimensionality. That way, when the
> function gets an arg of a higher dimension, it knows to iterate over
> the dimension. I have also chosen to not allow variable-length
> arg-lists, as I think it would be confusing. Array arguments serve the
> same purpose well enough.
>
> # function definition
> fn fname main_arg, array_arg[dim], keyword_arg=default
>
> flavors = ['apple', 'peach cobbler', 'pecan']
> pie{flavors}:eat # eat called with each flavor
>
> [1,2,3]:split # -> [[1],[2],[3]]

Here, I'm assuming "pie" is a dictionary. Previously, you gave examples of
dictionaries being indexed by strings or by regular expressions. What does
it mean for a dictionary to be indexed by a list? What about by a list of
lists? Is it possible for a dictionary to be indexed by a dictionary? And
what about a dictionary of dictionaries? What about a dictionary of lists?
What about a list of dictionaries?
[snip]
>
> The it keyword. it is a special variable which refers to the current
> iteration of the left-hand side of an assignment or a function call
> (before the :colon) or the whole thing if it is a singleton.
>
> # filtering
> old = [1,2,3,4,2,3,1,2,3,1]
> new = old if it != 1 # -> [2,3,4,2,3,2,3]
>
> # numbers can be searched as strings with pattern-matching
> new = old
> new<1>!pop # -> [2,3,4,2,3,2,3]

new is a list, so apparently you can run a regular expression on a list, and
only get the elements which match. That is, "new<1>" in the above, would
probably be equal to the list [1,1,1].

The statement "new<1>!pop" should then call pop(), passing to it the list
[1,1,1], and then replacing that list with whatever it is that pop()
returns.

You seem to be implying that pop should instead be called on the original
list called "new". I think the syntax should then be:

new!pop(<1>)

Where you're calling pop() on "new", and passing to it a regular
expression as an argument. The function pop() would then iterate through the
list, and remove any elements which match the regular expression.

But what if the children of "new" were something other than strings or
numbers? What if they were lists, or dictionaries, or regular expressions
themselves? How do you match a regular expression against a regular
expression?

- Oliver


.



Relevant Pages

  • Re: comments on my design of a new language?
    ... > indexed by a string or a regular expression, ... Trees are essentially nested dictionaries, ... I was originally going to treat scalars and unit lists equivalently, ... > dictionaries being indexed by strings or by regular expressions. ...
    (comp.lang.misc)
  • Re: comments on my design of a new language?
    ... Trees are essentially nested dictionaries, and this is the only place where unordered uniqueness occurs. ... Lists are ordered? ... Though it is not something most people would have use for, I have always wanted a mechanism for generating a random string that obeys a regular expression rule. ...
    (comp.lang.misc)
  • Fast Data Comparison (dict v. list. v string)
    ... many comparisons to fixed-size lists of fixed-length strings. ... my implementation uses dictionaries to store each string. ... all I have to do to compare the two ... it appears that strings are constant as I can't assign individual ...
    (comp.lang.python)
  • len() and PEP 3000
    ... I suggest that at least lists, tupples, sets, dictionaries and strings ...
    (comp.lang.python)
  • Re: Thoughts about Python
    ... I know that tuples can be used as keys... ... Mutable keys in dictionaries either need to be ... Using lists forced to strings would be a difficult sell even without the ...
    (comp.lang.python)

Loading