positron-lang / spec

Positron Language Specification
4 stars 1 forks source link

Paradigms #5

Closed renatocf closed 9 years ago

renatocf commented 9 years ago

This question should be created at some moment - and the motivation, at this moment, is choose how will be Positron's type system.

So, the question is: which paradigm should Positron use? Or, which should be Positron's main paradigm (in case it has features of more than one)?

renatocf commented 9 years ago

I'm give my opinion in a second post, to avoid polluting the question.

I believe that a good option is a multi-paradigm language - in a sense similar to what C++ has achieved. For a system language, procedural appears as a very natural way of controlling the computer. At the same time, object-oriented programming is (today) the most used paradigm for a high level design of problems. Mixing both, in my view, is essential for a modern system language.

At the same time, functional is becoming increasingly popular - mainly due to the creation of models for data access as MapReduce. C++, though born to add OOP to procedural C, was not prepared from day one to support functional behavior. I believe Positron could get some of functional characteristics (as 1st order functions) and use them as a way to simplify both procedural and OO implementations. Of course, as a compiled language, Positron will not have the full flexibility achieved by pure functional or dynamic languages. Even so, I believe we can support some of the nice features that made functional so popular.

If we agree with a procedural-oo-functional multi-paradigm language, I think it can be used to evaluate what would be the best type system for Positron - as being discussed in issue #4.

igorbonadio commented 9 years ago

I agree with you. I believe Positron should be multi-paradigm.

But in my opinion we should focus on the Object-Oriented paradigm. As I have studied here it is possible to use OO with no performance penalties. Of course, the use of interfaces, traits or other advanced things may slow down the program...

In a second layer, I think we should add some functional and procedural features.

Thing that I like in functional languages, and I believe Positron should have:

// (scala code)
// we could have something like:
var x = 1 // x is mutable
val y = 2 // y is immutable
# (elixir code... I dont like this syntax...)
Enum.filter(1..7, odd?) # => [1, 3, 5, 7]
// (scala code)
[1, 2, 3].map(x => x+1) // => [2, 3, 4]
# (ruby code)
[1,2,3].each do |x|
  puts x
end
-- (haskell code)
data Bool = False | True
data Shape = Circle Float Float Float | Rectangle Float Float Float Float
// (scala code)
// It is similar to haskell code... We can use it with pattern matching... but I think the meaning is diferente
case class Point(x, y)
// and we can use:
val x = Point(1, 2)
// (rust code)
enum OptionalInt {
    Value(i32),
    Missing,
}
// and we can use:
let x: OptionalInt = Value(123)
let y: OptionalInt = Missing
-- (haskell code)
Circle x y r = my_circle
-- (haskell code)
x = if x > 2 then "Ok!" else "No!No!"
# ruby code
def sum(a, b)
  a + b
end

And I just like one feature of procedural languages: Procedural languages are imperative (in the sense of describing an algorithm as a set of small instructions).

vinivendra commented 9 years ago

I agree with the point that an OO language with some functional features is best, but I would be careful not to try do adopt too many functional features; I feel some of them make a lot of sense in a functional environment, but not so much outside it. With that in mind, I'd like to make a few comments on the features you mentioned.

int i = 0;
if (...) {
    int i = 2; // Not ok! We already have a variable called i accessible from this scope.
}

This could be beneficial in avoiding accidental redefinitions. Also, one could argue that if a programmer is running out of names, his code should probably be refactored, and that two variables that mean different things should have different names. Then again, I use i's inside for's way to often not to admit this is a bit hypocritical.

My fear is that if we mix paradigms too much we might end up having most programmers confused by the paradigm that they understand less. Maybe I'm being too cautious with some functional features because I know very little about them; some of the features mentioned above have undeniable value. What do you guys think?

igorbonadio commented 9 years ago

In an OO language, a data type is an object too. You can see it as a sugar syntax to create a object with getters and setter:

case class Point(x, y)

is equal to

class Point
  int _x
  int _y
  def initialize(ax, ay)
    _x = ax
    _y = ay
  end
  def x
    return _x
  end
  def y
    return _y
  end
end

or as an Enum

data Bool = False | True

is equal

Enum {
  False,
  True
}

I think it is an elegant way to define a optional value, for example.

x = read() # read() returns an optional int
if (x.valid?)
  puts x
else
  puts "error!"

with pattern matching:

x = read()
match x
  Value(v) => puts v
  Missing  => puts "erro!"

Well, I think it is better to discuss each functional feature in other issue. I will create later.

phrb commented 9 years ago

Hi y'all!

@renatocf and I are working together this semester, and he told me about this project. I really liked to read the discussions on the issue tracker, and I'd like to ask two questions:

Let me come at this from an angle. As I understood it the purpose of Positron is to be a system programming language. What would be the most natural and easy paradigm (and type system, for that matter) for parallel programming in that context?

I say this because I feel most of us is first taught to program sequentially, and only later learns how to think and program in parallel. This makes parallel and concurrent programming very weird and error-prone for most programmers. Therefore everyone would benefit from a language in which it's easy and natural to program and think in parallel, especially in a world where multi-core processors are the norm.

In other words, I'd like to know if the consideration of the "multi-core era" and the idea of an inherently parallel language would weight in, or provide any insights for, the decision of the paradigm and type system of Positron.

What about the thin runtime, how big would it have to be to support an OO language?

Thanks for your time, hope to read more discussions!

igorbonadio commented 9 years ago

Hi @phrb .

I will give my opinion about your questions.

I would say that functional programing is a good paradigm to multi-core/distributed/parallel/concurrent software development. First because FP languages usually use immutable variables. And second because FP languages are not imperative (you dont think so sequentially like in imperative languages).

But there are some drawbacks. For example, they are not so easy to learn... there are a lot of concepts (like monads, monoids, functors, etc) that are very strange to imperative programmers. So I think it doesnt obey the first law.

I dont think multi-paradigm brakes the 0th and 2nd law. I believe OO is simple enough in current days. And, I think we will only add FP features if they were clear, simple, and if they are better than (if it exists) imperative alternative (for example, I don't think we need monads/functors/monoids in Positron... we have inheritance and composition...).

And I don't think it brakes the 3rd law. Ok, some OO features (like interfaces, traits, and messages) are slow... So, maybe we should limit some OO features... Or maybe not. Maybe it would not be a big deal... I really don't know at this moment...

renatocf commented 9 years ago

Just to cite a recommendation gave by Professor Alfredo, I believe we could take a look at Julia Programming Language. It seems to have nice solutions for @phrb questions, and perhaps we could use them for thinking about parallel and concurrent structures in Positron.

renatocf commented 9 years ago

This topic came with very nice questions, but I believe it deviated from its main focus: discuss Positron's main paradigms. From our previous comments, I think we agreed with some topics:

  1. Positron is an imperative language. It implies that it is not, in its base, functional (what would bring features as monads, functors and monoids). Notice the distinction between imperative programming and procedural programming.
  2. Positron is an object-oriented language, built from its imperative characteristics. As much as we can, we'll try to follow the philosophy "everything is an object".
  3. Positron will have functional features. First-order functions, lambdas and automatic type deduction are typically functional and can increase Positron's expressiveness.

In addition, I think we also pointed other interesting (and powerful) features:

I think that combining all these suggestions could guide us to a simple, yet very powerful, set of features.

Just a note about macros: although they may seem to act against the 2nd Law of Design (Standardization), we could build a standard library with containers, algorithms and shortcuts (produced with macros) that would became a basic tool for every Positron programmer. At the same time, macros could allow other library and framework programmers to extend the language for a specific problem (by creating Domain Specific Languages - DSLs). I think this topic may need more discussions, and because of that we can create an Issue for that.

In any case: do you think that items 1 to 3 could be Positron's main paradigms?

igorbonadio commented 9 years ago

I agree. And we can keep open the 3rd item, because, as you said, it is better to open other issues to discuss each FP feature.

vinivendra commented 9 years ago

Hi all,

I've been away a while learning Haskell, and I have to say that I have warmed up to a lot of the concepts that @igorbonadio mentioned. I still think some alternatives from imperative languages might be better, but I can see the advantage of many other functional features mentioned. In any case, I don't think this is the place to discuss this feature by feature (yet), but mainly the paradigm in general.

As for the other suggestions, @phrb may have a few points. Firstly, I would shift the question from "what paradigm would be better" to "what features can we add to improve development for multicore architectures"? This is to say, I don't think this should affect the paradigm choice, but I do believe it would be great to have a language that makes it easy to implement multicore code, especially if we could get parts of the code to run multicore on its own. Then again, this is a discussion for later.

Also, I do believe OO would improve clarity, rather than damaging it. I think most people have some dificulty with OO because they start out with procedural, just like they have difficulty with functional. I started learning with OO, so for me it's actually much clearer than procedural. It might not agree completely with the 2nd and 3rd laws, but then again, that's why the 0th law precedes them.

Finally, I think we're all starting to agree on a paradigm choice, so allow me to make a formal proposal so you can discuss: An OO based paradigm, with a primarily imperative basis, but accepting freely any functional features whenever they present better alternatives.

How does that sound?

igorbonadio commented 9 years ago

So Positron's paradigm is

  1. Positron is an object-oriented language, built from its imperative characteristics. As much as we can, we'll try to follow the philosophy "everything is an object".
  2. Positron is an imperative language. It implies that it is not, in its base, functional (what would bring features as monads, functors and monoids).
  3. Positron will have some functional features. It will accept freely any functional features whenever they present better alternatives.

is it correct?

vinivendra commented 9 years ago

I approve!