• Check out the relaunch of our general collection, with classic designs and new ones by our very own Pissog!

sly: a new programming language

chaos

Tournament Banned
is a Site Content Manageris a Battle Simulator Administratoris a Top Programmeris a Top Community Contributoris a Top Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
I have been working on a programming language for as long as I can remember. People have been bombarding me with questions and trying to extract information about it, so I figured I'd make a topic for all the programmers out there interested.

I really don't know what to say about it, so ask whatever is on your mind and we'll just go from there. As more is said, I'll try to update the first post with its history/motivation/philosophy/etc.
 
To start things off:

Glen said:
what exactly are the benefits to creating your own programming language? i know absolute zilch about programming, but do you intend to market it or something? or are things like this always usable by anyone?

Language design has always interested me. It's probably the closest thing I have, perhaps besides web-related technologies, to a "focus" in Computer Science. For the most part, this is a hobby project. However, I've been researching languages and compiler related technologies for about 5 years now so I feel like the time is right to make my contribution to the scene. There aren't any current languages out there that I believe "get it right." Some get very close, but fall short in some way or another in my opinion. I'd be happy to go over my list and explain what's wrong with every language out there and how I intend to correct it, but I won't unless asked as it will get very... lengthy :)

I don't really intend to market it. If anything, writing this language has helped me market myself. My skillset has grown quite a bit when I first started undertaking this project years ago (the government of Kentucky saw a working version of Tetra when I was 15 - you better believe they were impressed that a 15 year old could write an interpreter).

It'll be open source and useable by everyone.
 
hats off on the open source bit. there were plenty of things that i wanted to ask, but i guess a good start would be to know the noticeable features of the language, with some examples of syntax.

edit: i'm aware of the several flaws with the two programming languages i'm fluent with, namely PHP and Visual Basic, and some flaws of C, which i'm not too fluent with. but it would be really nice to have an expert criticism on these languages, especially C since i have been rigorously studying it for the past few months in my free time.
 
I've been programming in C (mainly for school), and while it is a simple and powerful language, it can be very dangerous if you aren't careful. A feature I missed from other languages was bounds-checking. It was very annoying and sometimes time-consuming to deal with.

Anyhow, what would be a good language to compare Sly with in terms of syntax. I guess what I mean is like how Ruby has a similar syntax to Perl.
 
My room mate is a game design major and talks about programming all the time. All I know is, understanding that kinda stuff seems tough. I don't know much about C++ but learning about it in class was a bitch.

I really don't have much to contribute to this conversation, but props to all you who use your knowledge of the programming language to make the world of internet and video games go round and round.
 
I'm not a real serious programmer, though I do web design on a free-time basis (and with only say, a year of light practice I'm fluent in HTML and CSS, advanced in JavaScript). I would definitely learn Sly when it comes out.
 
What languages have influenced sly the most, both positively and negatively? What sort of things have you drawn from those influences?

In addition, what sort of "paradigm" do you see sly fitting, if any? (ie functional, logic, imperative, whatever).
 
I don't have any specific questions at the moment, but as you know I'm very interested in this project and want to read some "walls of text" about it, so to speak.
 
Oy, there are so many languages around. Its great because all of them have such a unique feel to them. Even extremely similar languages like Java and C# are very different when you begin to program in them, let alone those languages that push your thinking to the next level.

Functional Languages were my first influence as a programmer. Not imperitive (C, Pascal, etc.) but Functional. Functional are languages like Lisp, Scheme, and Haskell. Lisp/Scheme can also fall under "symbolic computation" but lemme not rant on that :-p

I'm very interested in seeing the details of this language, and look forward to your future posts. Any cool constructs? Lua has cofunctions, Scheme has call/cc and hygenic macros, Perl has built in regex, Objective C is nice OOP (i'll try out Smalltalk eventually...), Functional languages have "lambda" and currying. Anything in particular that is ground-breaking?

Or are you looking at it from more like a C++, Java sort of thing. An attempt to "do it right" damnit for once?
 
some flaws with java are with the semicolons and ( [ { are annoying as hell. visual basic is better but we copied more code out of books. like everyone got an a if you tryed so i liked programming class. the best part was making a 7 card stud game though it took a couple weeks
 
i'm gonna group quotes together to help address all points

I've taken 3 semesters of C++... I'm interested to see what implementations you're pursuing.

lol what does that mean

some flaws with java are with the semicolons and ( [ { are annoying as hell. visual basic is better but we copied more code out of books. like everyone got an a if you tryed so i liked programming class. the best part was making a 7 card stud game though it took a couple weeks
what? i'd rather steer this discussion away from CS 101.

--------------------------------

What languages have influenced sly the most, both positively and negatively? What sort of things have you drawn from those influences?

In addition, what sort of "paradigm" do you see sly fitting, if any? (ie functional, logic, imperative, whatever).

Good question! I think this is the best way to start this post. Sly is a statically typed multi-paradigm language with type inference. I guess for the most part you could call it "functional" - but in reality, it joins together the benefits of all the concepts in a way that is consistent and elegant. I almost feel bad calling it "OO" since people conjure up thoughts of C++, Java, etc, but it is an advanced OO language as well. I'll show examples of what it looks like later on in this post, and why it's actually something to be excited about.

Positive influences:
Haskell - Haskell is, in my opinion, the best designed functional language out there. If you're looking for a pure functional language, go for Haskell, not Sly. Unfortunately, monads, in my opinion, are a bit of hack. The pure functional language concept is a great dream, but in reality it is too impractical to separate state from the language. Since Sly tags functions as pure when possible, it has the same theoretical advantages of a pure functional language, such as aggressive optimizations and the ability to parallelize algorithms with little effort but without the awkward separation of state from the core.

Python - What Smogon is written in. One of the most readable languages I've ever encountered, using indentation for grouping is genius. The philosophy of Sly has a lot in common with Python ("there should only be one obvious way to do it", "readability counts", "batteries included", etc). Some of the syntax is derived from Python as well. In addition, some of the "generator" concept is taken from Python as well but with a few changes here and there.

Lisp - Lisp doesn't try to baby the user, which I appreciate. If I learned anything from Lisp, it's that you should empower, not restrict. Morons can write bad code in any language. Just try not to _encourage_ it like Perl does.

Negative influences:
C++ - C++ has a few unique problems with it: it's slow to evolve, the language comes with little in the way of libraries, and it tries to bank on C's success. I am trying to avoid all of those.

Java - A language created for medium-level programmers that tries to shoehorn everything into an OO concept. The result? Too much verbosity. Sly is for the most part, the anti-Java.

Perl - Perl is cool as a text processing language. I am dissapointed that it evolved into being the kitchen sink :( I take Python's stance - Perl has all of the readability of an '08ers post, and that should be avoided at all costs. Sigils are stupid, too.

Lisp - I love the concept of Lisp, I just don't think it's practical. Prefix notation is verbose at times and the deep nesting of parens is hard to grok. Macros aren't worth it. In addition, the Common Lisp standard isn't evolving at all and most of the stdlib feels dated (lack of sockets, anyone?).

Here's what I've drawn:
* A language shouldn't restrict its audience.
* Semicolons and braces suck.
* Single dispatch, baby OO languages (think object.method() on everything) are impractical for large projects.
* Lisp style "no syntax, just parens" doesn't jive well. Syntatical impurities provide hooks for the eyes and make scanning large blocks of code easier. In addition, it's important to limit the amount of nesting. Humans aren't computers.
* Don't encourage sloppy programming, but don't make arbitrary hoops for programmers to jump through.
* Dynamic typing can be a boon for large projects - what's needed is a static language that feels like a dynamic one. i.e., don't worry about types, but if you fuck up the compiler will tell you instead of waiting a year for a subtle bug to pop up.
* Lazy is GOOD. Python and Haskell encourage this quite a bit. We go a bit more on the Python side as far as implementation of lazyness.
* A lot more!

hats off on the open source bit. there were plenty of things that i wanted to ask, but i guess a good start would be to know the noticeable features of the language, with some examples of syntax.
Anyhow, what would be a good language to compare Sly with in terms of syntax. I guess what I mean is like how Ruby has a similar syntax to Perl.
Syntax? Python meets Haskell. No object.method() nonsense. I'll give a few examples:
------------------------------------------------------------------------------------

Code:
# Print everything in an iterable of strings that has "big steelicks" somewhere in it.
steelicksfinder(i) = filter(find(, "big steelicks"), i)

# Lets use it... in many ways!
people = ["chaos", "big steelicks sucks", "big steelickssssss"]
steelicksfinder(people) # big steelicks sucks, big steelickssssss

f = file("dumb story.txt")
steelicksfinder(f) # Go through dumb story.txt, and select every line that has big steelicks in it.

# Hmm? A basic coroutine that yields nonsense.
dumbfunction() =
    while:  # while w/o argument is an infinite loop
        yield getrandomstr()
steelicksfinder(dumbfunction()) # years later, hopefully this generated some big steelickii!
One of the main features of this language is it's unique type system. As far as I know, it has the most powerful static type system in existence. Types are first class - you can manipulate the signatures of functions at compile time in arbitrary ways. What about a function to reverse an arbitrary sized tuple? The signature kind of looks like this: (syntax hasn't fully been decided on)

Code:
reverse{TL}(tuple{.. TL} t) -> {
                                R = []
                                for T in TL:
                                    R = T + R
                                R
                            }
Try doing that with Haskell. In addition, compile time analysis is possible as well. Regular expressions can be compiled at compile time, printf can be type checked, etc.

The type system is designed specifically around the application of functions. While Sly is technically an OO language, it surely doesn't feel like one. Lets try an example:

Code:
# In Python, strings have a predefined list of "methods".

# Hey, I want to strip a string!
print "       Shut up    ".strip()
# Hey, I want to split this string, and strip the parts.
print " Damb | Dooo | Cat   ".split_strip("|") # Hell no!

def split_strip(s, sep): 
    for item in s.split(sep):
        yield item.strip()

print list(split_strip("  Ok | Dumb | Example", "|")) # ok, here we go
Why should strip() be any more privileged than split_strip? They both are just functions that operate on a string. Why the difference? This is one of the problems found in todays "OO" languages - only predefined functions ("methods") may take advantage of the privileged syntax and other benefits that come along with it (virtual dispatch). With Sly, and multimethods, anyone can write a function that works on your data and it will look just like every other function - no more, no less.

One of the big advantages of this is that verbose "interfaces" aren't necessary (Java anyone?). Since an interface is defined by the functions it supports, why not just specify a type that supports those functions? In Sly, there is no "inherits Comparable, Cloneable, ...". Define the function it supports with that type, and the deed is done. Perhaps an example is in order.

Code:
# Define an object with length.
len(MyObject mo) = 3

len([1, 2, 3, 4]) # 4
len("cat dog") # 7
len(my_object_here) # 3

# Okay, we need a type that supports the length "interface". Do we make a separate interface and define that function in it?
# No! Boilerplate sucks.

T with len(T) -> int a_variable = (... some object that has a length ...)
Technically, the type declaration isn't even necessary, it has only been provided for examples sake.

Okay, I haven't even addressed syntax. Whitespace is signifigant - as you have seen. Indentation is used for grouping. However, whitespace within a line is also signifigant. All popular languages include the concept of "operators" - i.e. a + b, i - v, etc. The problem with infix operators is of course, precedence. Some languages don't allow arbitrary operators to be defined (which is restrictive), some allow people to define their own operators with their own precedence (which makes parsing a hell ride, and can also confuse the users) and some dont allow overloading at all (which is balls.).

The worst example I've seen is Smalltalk, which uses infix notation for all operators, but makes them have no precedence. The result? Parens hell. The biggest advantage of infix, aside from familarity, is the ability to describe expressions concisely. (a + b) == (c + d)? No thanks. That's just as bad as (== (+ a b) (+ c d)). So what to do? Use whitespace for grouping!

Yes, Sly allows you to define any operator you want for the most part, infix and prefix. Operators are just functions - there is nothing special about them except syntax. We define precedence by the whitespace surrounding them! This makes things easy to parse for the computer AND the human and still allows people to write concise expressions :)

Code:
a + b * d is parsed as (a + b) * d
a + b*d is parsed as a + (b * d)

a+b == c+d # Example above.

+(MyObject a, MyObject b) = 5
my_object + my_object2 # 5

**&(MyObject a) = 8
**&a # 8
Okay, I'm growing exhausted. That's enough for now. The main thing to get out of this is that Sly is an extremely powerful language, and being statically typed can save the programmer from errors and achieve C-like speeds :)

------------------------------------------------------

Even extremely similar languages like Java and C# are very different when you begin to program in them, let alone those languages that push your thinking to the next level.

I disagree... languages that share a paradigm are almost interchangable... the only difference is in libraries.

Not imperitive (C, Pascal, etc.) but Functional. Functional are languages like Lisp, Scheme, and Haskell. Lisp/Scheme can also fall under "symbolic computation" but lemme not rant on that :-p
Are you trying to lecture me on paradigms? ;-( Lisp isn't a language - it's a group of languages. Scheme is a functional Lisp, yes... (I think you're referring to Common Lisp, but that isn't a functional language in any way.)

Objective C is nice OOP (i'll try out Smalltalk eventually...)
Both of them are basic OO languages and not really worth your time. To be fair, there are very few advanced OO languages out there (CLOS, Dylan and Perl 6 are the only ones I know off the top of my head).

i'm aware of the several flaws with the two programming languages i'm fluent with, namely PHP and Visual Basic, and some flaws of C, which i'm not too fluent with. but it would be really nice to have an expert criticism on these languages, especially C since i have been rigorously studying it for the past few months in my free time.
Or are you looking at it from more like a C++, Java sort of thing. An attempt to "do it right" damnit for once?
The problem with the non-C languages here (Java, PHP, Visual Basic) is that were made specifically for "medium level" programmers. PHP got adopted quickly because it was _simple_ (it overtook the infinitely more powerful Perl for top web-development language). The PHP developers know about its shortcomings and they don't address them because they also know their target audience. I'm sort of pressed for time at the moment, but I think http://www.bitstorm.org/edwin/en/php/ will provide enough rationale for why PHP blows :) (It's one of my least favorite languages :()

Java anyone? It was marketed as a competitor to C++ with features cleaned up. By that, they mean they removed all of the power the language had with templates and operator overloading and tried to pidgeonhole you in its overly restrictive type system. The biggest problem I have with Java is that it tries to bank on the whole "OO works for EVERYTHING! ! !" bandwagon. Not everything is best represented by a class. I get sad when people describe Java as a "true OO" language as well - not only does it make the distinction between primitives and objects, but it also doesn't support advanced OO concepts (unless you consider "design patterns" advanced). Unfortunately, it falls short of being a competitor to C++ - not only is the latter faster and better supported by C libraries and native system services, it provides everything Java does and more.

The biggest problem I have with both is that they are unnecessarily verbose. I don't have time for boilerplate!

As for the C derived languages: C is one of the most beautiful languages out there. It succeeds at everything it tries to be - a portable, friendly looking variant of assembler. I can't really say the same about C++, but criticism of C++ is best left for another day.
 
some clarifications:

<@Surgo> chaos, why do you think lazy evaluation is good?
<@chaos|away> the way haskell does it isnt possible in sly
<@chaos|away> because its not purely functional
<+Brain> x || super_expensive_function()?
<@chaos|away> but sly is lazy in the idea that most of its functions work on "iterables", generators, coroutines, whatever you may call them
<@chaos|away> and it will take data from these iterables as needed
<@chaos|away> instead of trying to load it all into memory
<@Surgo> right
<@chaos|away> if youve worked with pythons concept of generators, then you know what im talking about
<@chaos|away> im not interested in dumbing down coroutines like python is though
<@chaos|away> if i can find more powerful uses for them i have no problem adding them into the language

<@Surgo> steelicksfinder(i) = filter(find(, "big steelicks"), i)
<@Surgo> I don't really understand what's going on here in find. Is the blank before , supposed to be an implied argument?
<+Brain> it's like lambda x: find(x, "big steelicks")
<@Surgo> ahh
<+Brain> it's shorthand for a partial
<+Brain> I was wondering the same thing the first time I saw it
<@Surgo> can you write that out longhand?
<+Brain> I like it though
<@chaos|away> ok
<@chaos|away> x => find(x, "big steelicks")
 
Wow, you've must have put a lot of thought into this already man, from the cutting edge of both functional and OOP programming. I really was expecting something a lot less ambitious than what you've laid out. (going for a type system more powerful than Haskell? o.O) I somehow doubt that I'd even learn half of what you plan at a University.

How much of it have you've done already? Even if its just the semantics, thats quite impressive. Any prototypes?

Are you trying to lecture me on paradigms? ;-( Lisp isn't a language - it's a group of languages. Scheme is a functional Lisp, yes... (I think you're referring to Common Lisp, but that isn't a functional language in any way.)

No, I was just wondering if you were going to implement any of the specific features. I do see where you're coming from however. Also, IMO, Common Lisp is multi-paradigm, and certainly has functional aspects of it. I've also seen lazy aspects Common Lisp around.

One last question for the hell of it. Has sly been influenced by logic programming in any way? (Prolog and whatnot)
 
I particularly interesting in learning what you think of the shortcomings of C++, and how you plan to address them (or have them be irrelevant) in Sly, as C++ is the language I'm learning right now.
 
Thanks for the responses chaos.

Another question, though this might be going too far into the future...

What would be the learning curve for implementing GUIs (if possible) with Sly? I know Java and C# are good candidates in terms of a low learning curve as opposed to...Visual C++. I'm using Java to implement the GUI in a small self project I'm working on .
 
Obi said:
I particularly interesting in learning what you think of the shortcomings of C++, and how you plan to address them (or have them be irrelevant) in Sly, as C++ is the language I'm learning right now.

One he has already addressed, which is single-dispatch in typical OOP languages.

Double-Dispatch in C++ requires the Visitor design pattern, which is rather inelegant. Having the language recognize double-dispatch and utilizing it automatically without having to resort to such an ugly design pattern would be of great benefit.

EDIT: Apparently you can implement multiple-dispatch with C++ template magic. But that also looks pretty ugly.

I'm interested in what other short comings chaos sees in C++ as well.
 
Wow, you've must have put a lot of thought into this already man, from the cutting edge of both functional and OOP programming. I really was expecting something a lot less ambitious than what you've laid out. (going for a type system more powerful than Haskell? o.O) I somehow doubt that I'd even learn half of what you plan at a University.

As I said, research into this language and implementation strategies has been going on for around 5 years. I strive for excellence, and I want to make something useful. The language actually has a large history behind it, I'll write it up sometime when I'm less pressed for time.

As for the university comment, I've been programming for 9 years now, self-taught. There is no way you could try to fit in all the experiences I've had writing real world applications and the years of research I've put into this language design into a textbook course.

The type system is as powerful as possible out of a static system. Types can be manipulated at compile time like any other datum - you can literally do whatever you want. The only restriction is that the algorithm used for determining the type of a function must be pure. I can't have f(int) -> string one time and f(int) -> FFFFFFFFFFFF another time.

How much of it have you've done already? Even if its just the semantics, thats quite impressive. Any prototypes?
Most of the work I've done is research and planning, which is the most important part anyway. I started working on an implementation nearly a week ago. It can parse your input and display it in a pretty tree format, but I haven't gotten much farther than that. I am using http://llvm.org the Low Level Virtual Machine as my backend - think of it as an assembler that can be ported to any architecture. In addition, it provides some other benefits like JIT and some optimizers. I plan to contribute back to this project.

I'm hoping to get some basic functionality within the month, and a stable release within 2 years. Releases will be made with varying degrees of "beta", but I want to set aside a good healthy chunk of time to make sure the implementation is rock solid and ready for consumption. The core language is fairly small - most of what needs to be written can be implemented in libraries. I hope to get the support of programmers at Smogon and my university to help out.

Also, IMO, Common Lisp is multi-paradigm, and certainly has functional aspects of it. I've also seen lazy aspects Common Lisp around.
Of course, CL does everything :) I just wouldn't classify it as functional

One last question for the hell of it. Has sly been influenced by logic programming in any way? (Prolog and whatnot)
The only logic language I've used extensively is SQL, and I wouldn't say it's been particularly influenced by SQL. Some pattern matching is done, but I wouldn't really attribute that to Prolog or anything. I'm sure it wouldn't be hard to implement logical features if needed. The core of Sly is that weird mix of OO and functional which seems to work so well in concept - it works fine enough that I'd rather not randomly try to bolt another way of doing stuff onto it (see: C++ ontop of C).

I particularly interesting in learning what you think of the shortcomings of C++, and how you plan to address them (or have them be irrelevant) in Sly, as C++ is the language I'm learning right now.

Ok:

C++ doesn't have true anonymous functions (several lambda libraries have been published though using the template system) or closures. Sly will.

C++'s advancement is stagnant. Design by committee sucks. Sly is designed by... me.

C++ only supports basic OO. Sly supports multiple dispatch.

C++'s syntax is balls, IMO. I like Sly's syntax!

C++ isn't lazy enough by design.

The STL sucks. Template error messages are cryptic at best, suicide at worst.

C++ doesn't have a module system. Namespaces are half-hearted, at best.

C++ doesn't have an Application Binary Interface. Ever tried to get two C++ programs compiled with different compilers to talk to each other?

C/C++ is done in a single pass. i.e., you have forward declare stuff you use later on... etc... verbosity...

C++ doesn't have coroutines. So... useful...

etc.

Thanks for the responses chaos.

Another question, though this might be going too far into the future...

What would be the learning curve for implementing GUIs (if possible) with Sly? I know Java and C# are good candidates in terms of a low learning curve as opposed to...Visual C++. I'm using Java to implement the GUI in a small self project I'm working on .

It depends on what kind of libraries people make for it! Nothing about a GUI is implemented in the core language for sure.
 
Code:
# A basic example of type inference.

# What's the type of this function?
steelicksfinder(i) = filter(find(, "big steelicks"), i)

# Start basic...
find(str haystack, str needle) -> bool
find(, "big steelicks") -> (str haystack) -> bool

# Figure out filter...
filter{T}(T -> bool, iterable{T}) -> iterable{T}
filter(str -> bool, iterable{str}) -> iterable{str}

# Derived from filter's signature
# i was passed as the second argument of filter - it has to be iterable{str}.
# return type is filter's return type
steelicksfinder(iterable{str} i) -> iterable{str}
 
The only logic language I've used extensively is SQL, and I wouldn't say it's been particularly influenced by SQL. Some pattern matching is done, but I wouldn't really attribute that to Prolog or anything. I'm sure it wouldn't be hard to implement logical features if needed. The core of Sly is that weird mix of OO and functional which seems to work so well in concept - it works fine enough that I'd rather not randomly try to bolt another way of doing stuff onto it (see: C++ ontop of C).

I figured that as much. For better or worse, I've stuck myself into doing research into logic and logic programming currently and it really isn't nearly as exciting as how Functional and OOP paradigms have been going.

The big thing I'd say in Logic Programming currently (from a beginner's point of view) is Constraint Programming. It seems quite useful to program in constraints, but I've never actually done it myself. According to wikipedia, people have fit it into various imperative programming languages, so it must be possible somehow.

C++'s advancement is stagnant. Design by committee sucks. Sly is designed by... me.

Talking about "design by committee"... Did you read up on R6RS Scheme? The de-facto standard for a long time was R5RS, and now R6RS has been approved. Scheme is now case-sensitive, has a standard library and all these other things that make it look like Common Lisp. >_>
 
I love how Lisp is both a positive influence as well as a negative one. Also, I like what you've done so far :)
 
Okay, first of all: I'm a huge advocator of lazy evaluation as opposed to strict, so good job there.

Secondly, a little quibble. Personally, I don't like the fact that a + b * d is parsed as (a + b) * d. It should parse as a + (b * d), since multiplication should take precedence when both operators are 'spaced out' (and hence, have the same precedence). BEDMAS rule precedence should apply if you don't 'space them out/bind them together'. Of course, I like that you can type (a+b)*d as a+b * d, but I would suggest parsing a + b * d as a + (b * d). In short, there should be an internal precedence for the operators in my opinion.

I don't know if you made a mistake there or if you did that intentionally, but BEDMAS rules are universally accepted by everyone. Actually, BEDMAS rules allow you to get rid of parentheses, as you say you want to do: a*b^2+c can be written without any brackets and means (a*(b^2))+c to everyone.

Other than that, good job, and good luck.
 
Okay, first of all: I'm a huge advocator of lazy evaluation as opposed to strict, so good job there.

Secondly, a little quibble. Personally, I don't like the fact that a + b * d is parsed as (a + b) * d. It should parse as a + (b * d), since multiplication should take precedence when both operators are 'spaced out' (and hence, have the same precedence). BEDMAS rule precedence should apply if you don't 'space them out/bind them together'. Of course, I like that you can type (a+b)*d as a+b * d, but I would suggest parsing a + b * d as a + (b * d). In short, there should be an internal precedence for the operators in my opinion.

I don't know if you made a mistake there or if you did that intentionally, but BEDMAS rules are universally accepted by everyone. Actually, BEDMAS rules allow you to get rid of parentheses, as you say you want to do: a*b^2+c can be written without any brackets and means (a*(b^2))+c to everyone.

Other than that, good job, and good luck.

The problem is that * isn't "multiply" - it's the function *. Maybe i'm not using it to multiply? It's not a multiplication operator. Sly works with many domains besides mathematics. I appreciate that you're trying to help me out, but there are a lot of rammifications to using predefined precedences for operators.

Sly's "operator" system is fully generalized. -b is the function call - with one argument, b. If I want to overload - for a certain object, then I define the function -(MyObject a). a * b is the function call *(a, b). *%!@ is the function call *%!@(MyObject a, MyObject b). By putting in predefined precedences, it makes it a lot harder to allow the user to define arbitrary prefix/infix operators. Lets think of the options we have with predefined precedences:

A. Don't allow the user to define their own operators. This is unsatisfactory for many reasons. It gives preference to arithmetic, regardless if the domain you are in actually uses it or not. In addition, other domains of work are left out in the cold if they want their own precedences. For instance, this was a problem with the Spirit parser framework in C++. I'm not pretending I know everything about what you're writing - so I'm going to take a step back and let you define whatever operators you want.

B. Allow the user to define their own operators, but make them neutral precedence. This puts an arbitrary barrier between the "core" language and the "user-defined" language. Sly should give the same benefits to people extending the language as it does to the core.

C. Allow the user to define their own operators, with precedence, fixity, etc. This makes parsing a nightmare for computers and humans. Also, it makes the abstraction of "modules" harder. Does your module define a new operator? Well, just importing it changes the way the document is parsed! Humans have to remember a buttload of new information and the ambiguity introduced reduces confidence in the programmer. "Is this right? Let me check my operator precedence table. Oh fuck! I forgot which modules I imported!"

The main problem with allowing user defined operators with precedence and fixity is that it requires you to execute the language to parse it. You have to take in consideration that more than compilers will be trying to understand the language. Text editors? Documentation tools? Blah. I like a clean separation between syntax and content.

------------------------------------------------

The biggest conceptual problem with putting in operator precedence is that operators no longer retain their clean one-to-one mapping with functions. As such, it is much harder to fully generalize them to allow the language to be extensible.

To recap:

* Using whitespace around operators allows the system to be fully generalized, and thus extensible in any way you wish without introducing unnecessary complexity to the language.
* Precedence is explicit, and thus makes sense for the domain you're doing, not just math. To be fair, * and / having higher priority in mathematics isn't even _true_. Multiplication is done by joining the terms together - 3x, y(a + b), etc. Division is done by placing the bar as such:

a + b - d
---------
5cd - 8a

The whitespace approach is actually inspired by true mathematical notation. Mathematicians have more than one dimension to work with - they can put their stuff vertically, make things bigger, make stuff higher, make stuff lower, etc. a + b*d is more similar to a + bd of math than putting arbitrary precedences anyway - notice how in math notation, the higher precedence operators are grouped different visually. There's no question that 5cd is a unit - there's no whitespace to say otherwise. The division bar clearly divides those two expressions - how else would you do it?

Explicit precedence is a good thing :)
 
Back
Top