Syntax tweaks

17 views
Skip to first unread message

Mike Austin

unread,
Oct 30, 2011, 4:37:46 AM10/30/11
to magpi...@googlegroups.com
I've spent several hours now playing with magpie, and am beginning to love it.  Most everything just makes sense.  I have a few suggestions that can be taken with a grain of salt:

1. defclass - I know it is defining a class, and it sounds like CLOS, but I'm so used to other languages that the "def" seems redundant. What if it was just "class"?
2. I don't like using symbol vs keywords for everything, but I feel "is" could be replaced with "::" in type patterns. I feel it visually gives you separation, rather than having 3 words together (eg. "foo is Int" vs "foo :: Int") It's also what Dylan and Haskell uses.
3. Would it be possible to create class constructors without "new"? for Example, "Point(x, y)" instead of "Point new(x, y)". It's easy to define a method which does this, but it would be nice if this style of constructor was created when you define a class.

Here's an example of these 3 tweaks in action:

class Point var x var y end

def (this == Point) init(x :: Int, y :: Int) this init(x: x, y: y) end

val point = Point(x: 2, y: 3)

Subtle, but for me, makes it easier to visually read and parse. Of course, I could dig into the magpie code and try these out, but I wondered if anybody had any thoughts about them first.

Mike

Andrew

unread,
Oct 30, 2011, 8:03:49 AM10/30/11
to magpi...@googlegroups.com
On 30 Oct 2011, at 08:37, Mike Austin wrote:
> I've spent several hours now playing with magpie, and am beginning to love it. Most everything just makes sense. I have a few suggestions that can be taken with a grain of salt:
>
> 1. defclass - I know it is defining a class, and it sounds like CLOS, but I'm so used to other languages that the "def" seems redundant. What if it was just "class"?
I too would prefer simply "class".

> 2. I don't like using symbol vs keywords for everything, but I feel "is" could be replaced with "::" in type patterns. I feel it visually gives you separation, rather than having 3 words together (eg. "foo is Int" vs "foo :: Int") It's also what Dylan and Haskell uses.
I also find :: easier to parse, though that may just be because of my experience with languages that tend to prefer symbols over words.

It would also be easier to read with syntax highlighting, and I personally have no qualms with relying on syntax highlighting in this day and age to aid readability, so long as it's not completely unreadable without it.

I think :: will be too easily confused with type annotations (which it is in Haskell), when it is in fact pattern matching. I think "is" communicates this quite well - as soon as I saw it I thought "that's an odd choice to use for type annotations - ooh, wait, are they using pattern matching here?!"


> 3. Would it be possible to create class constructors without "new"? for Example, "Point(x, y)" instead of "Point new(x, y)". It's easy to define a method which does this, but it would be nice if this style of constructor was created when you define a class.

Personally I prefer the clean separation between a method and the slightly magic (though less so than a lot of other languages) object creation. Further, to me having a method that operates on the class makes perfect sense to me and fits all my mental models, whilst having a class behave like a method doesn't.

Mike Austin

unread,
Oct 30, 2011, 2:14:30 PM10/30/11
to magpi...@googlegroups.com
I'm glad you prefer just "class" also :)  And for the constructor thing, as long as it's possible to write the way I would like without changing the language, that's good enough for me.  But as for "::", I still prefer it over "as":

def (this :: View) addSubview (subview :: View)
    subview parent = this
    this subviews append (subview)
end

val isa is Int

val isa :: Int

The first version above is full of words.  I'm just used to type annotations being some symbol like "::" or "<".  I won't harp on the subject any more, it's just a preference I'd like to share.

On a side note, how far can we take immutability in magpie?  Should I define the above sample as something like this instead?

def (this :: View) addSubview (subview :: View)
    return this subviews append (subview copy(parent: this))
end

And depend on optimized tail recursion?

Mike

Andrew

unread,
Oct 30, 2011, 2:36:54 PM10/30/11
to magpi...@googlegroups.com

On 30 Oct 2011, at 18:14, Mike Austin wrote:
>
> The first version above is full of words. I'm just used to type annotations being some symbol like "::" or "<".

That was half of my point. They're not type annotations, they're pattern matching on type. There's a difference:

* The pattern matching doesn't give any type checking.

* Type annotations are limited to only to types. Pattern matching is a lot more flexible (silly example alert):
def (this == 0) isZero
true
end

def (this) isZero
false
end

Using something that looks like type annotations confuses the mechanics in people's minds and limits the scope of their ambitions as to what they can do with it.

Also, if you're used to "::" being type annotations - or even if not for that matter - this looks weird:

match foo
case :: Int then print("Int")
end

It'll become even more important if/when (I don't know the plans) actual type annotations come back. I think using the same symbol as other languages use for type annotations will confuse people a lot more. If type annotations do come back, I'd really like "::" to be used for it.

Of course, all my arguments are against using something that is used for type annotations in other languages. If you can come up with a good symbol that means "is of type" that isn't used for type annotations in other languages I may be on your side (I am used to symbol heavy languages, after all) but as it stands, I can't come up with one myself.

Mike Austin

unread,
Oct 31, 2011, 1:31:12 PM10/31/11
to magpi...@googlegroups.com
The only other character I've seen used and can think of for types is '@':

def (this @ View) addSubview (subview @ View)

match foo
    case @ Int then print("Int")
end

But I don't that if that's any better.  I'll stick with is :)

match (foo: a, bar: b)
    case a is Int then print("Int")
end

Bob Nystrom

unread,
Nov 3, 2011, 2:07:58 AM11/3/11
to magpi...@googlegroups.com
Whoa, a long thread about Magpie. How delightful! Answers to your
posts all mixed together:

> 1. defclass - I know it is defining a class, and it sounds like CLOS, but I'm so used to other languages that the "def" seems redundant. What if it was just "class"?

I find defclass tedious too, and it was just class for a long time.
The problem is that classes are first class in Magpie so it's fairly
common to have a variable that holds a class. It's nice to be able to
call that variable "class". I always felt that "klass" and "clas" and
stuff like that was awkward in other languages.

One thing I noticed is that reserved words are a rarely complete
common nouns. They are either non-noun words like "while" and "for" or
abbreviations like "int" and "bool". That leaves as many nouns free as
possible for use as variable names. So the idea with "defclass" was to
free up "class".

I'm not crazy about it but I have gotten more used to it. I find
something strangely appealing about both methods and class definitions
starting with "def" but I'm open to other ideas. One possible one
would be to make "class" a contextual keyword, so you would do:

def class Foo
...
end

And in that context it would define a class, but it's otherwise
available for use as an identifier. That feels a bit fishy too,
though.

> > 2. I don't like using symbol vs keywords for everything, but I feel "is" could be replaced with "::" in type patterns. I feel it
> visually gives you separation, rather than having 3 words together (eg. "foo is Int" vs "foo :: Int") It's also what Dylan and
> Haskell uses.

> I also find :: easier to parse, though that may just be because of my experience with languages that tend to prefer symbols over words.

I went back and forth between those for a while. I think :: was the
winner at first. I ultimately went with "is" because:

1. Magpie generally prefers words over punctuation ("end", "then", etc.)
2. "is" isn't any longer than "::".
3. It reads well and explains exactly what it means.

I find syntax highlighting is critical, though. I have some crappy
TextMate bundle slapped together that highlights "is" and that makes a
world of difference. Without syntax highlighting, Magpie quickly
becomes a wall of text.

> 3. Would it be possible to create class constructors without "new"? for Example, "Point(x, y)" instead of "Point new(x, y)". It's easy to define a method which does this, but it would be nice if this style of constructor was created when you define a class.

I like that about Python. I went with a single "new" method even
though it's less terse for one main reason: It makes construction
"first-class". In other words, you can do this:

def makeThing(class, arg)
class new(arg)
end

By making a single "new" method that takes the kind of object to
create as an argument, you can make object construction...
parameterizable? If we just made methods for each class name, you
wouldn't have an easy way to construct an object generically.

That being said, you're of course always free to make a little helper
method that instantiates a class. The regex module has exactly that so
you can do:

regex("foo")

instead of:

Regex new("foo")

> I think :: will be too easily confused with type annotations (which it is in Haskell), when it is in fact pattern matching.

I think of it more or less as both. Strictly speaking it is indeed a
pattern, but it conveniently also identifies the type of a variable,
so you could treat it as a type annotation too.

> On a side note, how far can we take immutability in magpie? Should I define the above sample as something like this instead?

Take it as far as you want, but don't feel you need to. I find
mutability really convenient as small scales and within a single
thread, but problematic across large programs or when concurrency is
involved. So my plan is that Magpie will have nice language support
for immutability and will ensure that there is no shared mutable state
across threads. At the same time, it has friendly mutable collections
(list) and has no problems with classes that have mutable fields.

I want immutability to be a tool you can use when you want (and I want
Magpie to make it easy to actually express immutability), but not
something you have to do to please the language.

> It'll become even more important if/when (I don't know the plans) actual type annotations come back. I think using the same symbol as other languages use for type annotations will confuse people a lot more. If type annotations do come back, I'd really like "::" to be used for it.

"Plan" is too strong a word for it, but my long term hope is that
patterns could be used directly for static analysis too, so you
wouldn't need a separate type annotation syntax. Because pattern
matching combines both testing (and you can test for type) and
variable binding, that gives you all you need to know "foo is of type
Bar", which sounds like a type annotation to me.

Once you start really thinking about types (generics, etc.) it gets a
lot more complex which is why I'm not worrying about it now, but I'm
hoping that just type-based patterns will be enough to get some of the
benefit that static types give you in other languages. At the very
least, I find type patterns help document what my methods expect, and
I really like being able to define methods and know that they will
only be called if their arguments are of the right type.

All I'd want beyond that is some static analysis for finding some
errors, and being able to use dataflow analysis to generate better
code. Given how hilariously primitive Magpie's current implemention
is, though, that's a good ways off. :)

Cheers!

- bob

Reply all
Reply to author
Forward
0 new messages