Re: [scala-language] The cake’s problem, dotty design and the approach to modularity.

540 views
Skip to first unread message

Shelby

unread,
Jul 18, 2015, 9:51:18 AM7/18/15
to scala-l...@googlegroups.com
I believe this post is illuminating. I hope to get some feedback.

I believe I show herein the fundamental importance of objects (as in "OOP"), that subclassing (but not subtyping) is fundamentally an anti-pattern, and that the new DOT calculus is essential.

For the goal of completely solving the Expression Problem, I believe the requirement for a "global vtable" which I pondered upthread, is implicitly fulfilled by the injection of inversion-of-control I had proposed.

Objects are passed around as the vtable, which I believe is a form of the extensible modularity advantage Martin was referring to in the thread "Usefulness of OOP":

https://groups.google.com/d/msg/scala-language/PIhmEeMg-Ms/3AE0udamW5EJ

Here is my example which afaics (?) could not be achieved with subclassing (i.e. virtual inheritance with a vtable bound to each instance) without the overhead of reconstructing a copy of the List with "pimp my library" instances:

trait Drawable[T] {
  def draw(o: T): Unit
}

class Point(x: Int, y: Int)
class Line(a: Point, b: Point)

implicit object LineDrawable extends Drawable[Line] {
  def draw(line: Line)...
}

// OT: below I'm pseudo-coding a hypothetical `List[T]` design that can't throw an exception when accessing head which last time I checked some years ago Scala's standard library design unfortunately does.

def draw[T](list: List[T])(implicit drawable: Drawable[T]) { list match { case Head(head) => drawable.draw(head) case Nil => } }

draw(List(Line(Point(0,0), Point(1,1))))

trait DrawableMorphed[T] {
  def drawMorphed(o: T): Unit
}

implicit class MorphedDrawable[T](drawable: Drawable[T]) extends DrawableMorphed[T] {
  def drawMorphed(o: T) { drawable.draw(o) } // OT: code for morphing of input `o` is not shown, given it is irrelevant noise to what is being elucidated
}

def draw2[T](list: List[T])(implicit drawable: DrawableMorphed[T]) { list match { case Head(head) => drawable.drawMorphed(head) case Nil => } }

def draw3[T](list: List[T])(implicit drawable: Drawable[T]) { draw2(list) }


The subclassing anti-pattern rears its ugly head again though as implicit subsumption as in the following example:

class Box(a: Point, b: Point, slope: Point) // OT: to insure the construction can't throw an exception, use only the diagonal corners and slope of one of the edges

implicit object BoxDrawable extends Drawable[Box] {
  def draw(box: Box)...
}

draw(List(Line(Point(0,0), Point(1,1)), Box(Point(0,0), Point(1,1), Point(0,1)))) // Error: no implicit found for Drawable[Any]

I assume the new DOT calculus will instead implicitly subsume `T` to `Line ∨ Box` instead of `Any`?

Perhaps the Dotty compiler could automatically generate the implicit object `Drawable[Line ∨ Box]`. Thus we retain subtyping (i.e. `Line` and `Box` are subtypes of `Line ∨ Box`) while eliminating subclassing (i.e. there is no nominal type which is the supertype of `Line ∨ Box` or at least `Any` should only occur with a cast since I've shown it discards extensible static typing). I am not clear if this is modeled by the fine grained methods structural typing in DOT that Adiaan Moors alluded to in the context of a prior discussion about a union type in one of the Scala discussion group threads (can't seem to locate it quickly at the moment); or if could be modeled in the compiler employing a monad, e.g. see the `sequence` conversion of `List[Thing[T]]` to `Thing[List[T]]` where the disjunction would be a list of types in the disjunction such as `DisjunctionList[Drawable[T]]` converted to the necessary implicit `Drawable[DisjunctionList[T]]`:


Another benefit of deprecating subsumption via subclassing in favor of subtyped disjunction, is distinct invariantly parametrized types can be added to the same List:

class TaggedLine[Tag](a: Point, b: Point, tag: TAG)...

draw(List(TaggedLine(Point(0,0), Point(1,1), 1), List(TaggedLine(Point(0,0), Point(1,1), "1"))) // Error: can not subsume to List[TaggedLine[Any]] because TAG is invariant

I assume the new DOT calculus will instead implicitly subsume `TAG` to `Int ∨ String` instead of `Any`?

Somewhat OT, I am pondering how will DOT deal with the following?

trait Invertible[T <: Invertible[T, A, B], A, B] {
  def to(a: A): B
  def from(b: B): A
}

object AB extends Invertible[AB, A, B] {
  def to(a: A): B...
  def from(b: B): A...
}

object CD extends Invertible[CD, C, D] {
  def to(c: C): D...
  def from(d: D): C...
}

def to[T, A, B](invertible: Invertible[T, A, B], a: A): B = invertible.to(a)

f(AB ∧ CD, new A)
f(AB ∧ CD, new C)

So the Dotty compiler has to automatically supply:

object `AB  CD` extends Invertible[`AB  CD`, A ∨ C, B ∨ D] {
  def to(a: A): B...
  def to(a: C): D...
  def from(b: B): A...
  def from(d: D): C...
}

On Sunday, July 5, 2015 at 11:50:07 PM UTC+8, Shelby wrote:
Coming back to this ... and sorry no time to construct a blog too rushed ...

To summarize ideas against premature specialization (not claiming these are original ideas):

1. Don't use subclassing, i.e. don't implement any method in a supertype (e.g. `trait`) that isn't `final`, thus all methods are final (closed) in their existential type[1].

2. Subtyping should only be injected locally at the call site with inversion-of-control (c.f. my ideas upthread for potential new forms of compiler assistance), or globally due to the Liskov Substitution Principle resulting from type constructors of kind >= 0 (a.k.a. type parametrization) and first-class functions (a.k.a. functional programming, i.e. functions can evaluate and return functions).

3. Functional programming is differentiated from imperative programming in that the semantics are expressed more unified (atomically, i.e. higher-level) — of which premature specialization employing discarded semantics[2] (which includes unrolling function recursion replaced with loops and mutable variables), mutable variables[3], or referential opaqueness are egregious cases. Category theory can raise this up another level.

Several resources[1][4] seems to confirm the criticism that Scala while being high-level, introduces more complexity than Haskell.

Most of the aforementioned premature specializations Haskell makes difficult to introduce (which the Scala programmer could choose to avoid but isn't discouraged from doing so), except apparently Haskell can't do the implicit global subtyping due to LSP (in #2)—such as adding elements of different types to a list—because refinement types are impossible due to bottom populating all types, i.e. Haskell can't do the new injunction and disjunction types of the DOT calculus (Dotty)![5]

...
 
Except apparently the lack of subtyping (refinement types) in Haskell is a major weakness (even after we remove subclassing, which is an anti-pattern) which means DOT (Dotty) could potentially take a big leap ahead? Is this paucity the price paid for Haskell's revered brevity?



"5. It should have a rich type structure that permits introduction of new abstract types and which supports modular program development.  By giving short shrift to expressions and evaluation, imperative language have an impoverished notion of type—and not support for modularity.  Worse, object-oriented programming, a species of imperative programming, is fundamentally antimodular because of the absurd emphasis on inheritance and the reliance on class-based organizations in which functionality metastasizes throughout a program."


"Scala also has the ability to namespace a function by giving special status to one of its arguments (some people call this OO, then don’t, in the very next breath – I never get it). What I mean is, you may have two functions with the same name, which are disambiguated at the call site by the type of the argument to the left of the dot. I am deliberately not calling this by any special name, but rather focussing on its utility – Haskell can do this with qualified imports – not quite so nice. I am usually, though not always, particularly unimaginative when it comes to inventing function names – allowing me to reuse one without a penalty is very handy indeed. Note here I do not mean overloading – I think the Scala community has worked out that overloading is just not worth it – do not do it, ever."


"I must associate a provenance with that bit in order to give it meaning.  “This bit being true means that e and e’ are equal, whereas this other bit being false means that some other two expressions are not equal.”  Keeping track of this information (or attempting to recover it using any number of program analysis techniques) is notoriously difficult.  The only thing you can do with a bit is to branch on it, and pretty soon you’re lost in a thicket of if-the-else’s, and you lose track of what’s what.  Evolve the program a little, and you’re soon out to sea, and find yourself in need of sat solvers to figure out what the hell is going on."

"It’s just that Boolean thinking has infected the software world to such an extent that I feel that I have to fight back. Just the idea of comparison to “null” to obtain a Boolean is absurd, even if you think you need a “null” pointer (which you don’t, in a properly designed language)."


"2. It should support both computation by evaluation and computation by execution.  Evaluation is a smooth generalization of high school- and university-level mathematics, and is defined in terms of standard mathematical concepts such as tuples, functions, numbers, and so forth.  Variables are given meaning by substitution, and evaluation consists of simplifying expressions.  Execution is the action of a program on another agent or data structure conceived of as existing independently of the program itself.  The data lives “over there” and the program “over here” diddles that data.  Assignables (my word for what in imperative languges are wrongly called variables) are given meaning by get and put operations (fetch and store), not by substitution.  Execution consists of performing these operations."

http://joshbassett.info/2013/hello-haskell-goodbye-scala/

"These tools exist and are as useful as they are, because of certain fundamental properties of Haskell itself. Here I mean, the hoogle function is only as useful as it is because Haskell tags IO effects in the type delineating values with types IO t and t, so hoogling for say, [a] -> Int eliminates a lot of candidate functions that would have this type in other environments. In Scala, without the delineation between an Int that has been computed with its arguments, and an Int that has been computed with the entire universe, a hoogle-equivalent would not be as useful"


... 

Shelby

unread,
Jul 18, 2015, 9:53:20 AM7/18/15
to scala-l...@googlegroups.com

Vlad Patryshev

unread,
Jul 18, 2015, 4:17:38 PM7/18/15
to scala-l...@googlegroups.com
I would not seriously involve LSP into solving this kind of problems. LSP is for explaining things to beginners, not for solving problems in "applied category theory" (as some people call programming these days).

One of the solutions is to think about a natural transformation from a covariant functor to a contravariant functor (List[+T] => List[-T]).

Thanks,
-Vlad

On Mon, Jun 15, 2015 at 11:52 PM, Shelby <she...@coolpage.com> wrote:
Thinking about how this relates to the problem of loss of specialization (restriction) due to inheritance subsumption:


Afaics, the generalized, paradigmatic solution to the above linked problem is:

List[+A] {
  def contains[B <: A](x: B)(implicit areEqual: (A, B) => Bool): Bool
}

where inheritance is not used for the types of A and B. For example, a Number can implement a Ordered and an OrderedDivisable typeclass (which can be tested with an implicit input parameter), but it doesn't inherit from those interfaces. Whereas, the type of A is covariant so that we may assign return values of type List[T] which BTW should be intersections of types in the container instead of a subsumption of types in the container (as is now the case in Scala 2.11).

Again it would be ideal if the future compiler would automatically create the apropos areEqual with the requisite match-case boilerplate to extract the types from the intersection and call the extant instances of areEqual for each type in the intersection.

In other words, it appears the intersection and union types of DOT are essential to play correctly with forsaking premature restriction via premature inheritance of types. Inheritance should only come into play where it is unavoidable due to Liskov Substitution Principle and therein the compiler should automatically do the match-case boilerplate for us.

Thoughts please?

On Tuesday, June 16, 2015 at 9:00:25 AM UTC+8, Shelby wrote:
On further thought, why can't the future compiler expand that boilerplate for us, even the match-case boilerplate (done at caller site thus VM type erasure is irrelevant) where T is an intersection types that each have an implementation of Desired[_] available in the current scope, so then we only need to write:

def f[T](a: List[T])(implicit b: Desired[T])

Or better yet the sugar where the compiler does the boilerplate internal to the function too:

def f(a: List[Desired])

It seems Haskell has modularity correct with typeclasses instead of inheritance?

On Tuesday, June 16, 2015 at 7:49:11 AM UTC+8, Shelby wrote:
def f[T](a: List[T], b: Desired[T]) ...

I note that the Dotty Dependent Object Types calculus is orthogonal to mixin inheritance modeling because of the potential for overlapping premature specialization. Also I note that typeclasses are nearly a complete solution to the Expression Problem and I do not recall which of the "issues" (are even really issues?) I had enumerated are due to the typeclass pattern and/or the coinductive type system of Haskell (where _|_ is the Top type, not Bottom as in an inductive language such as Scala):


(luckily I was able to capture the above document from a google cache after stackoverflow deleted it)

A typeclass in Scala appears to me to just be a way of specifying an interface that many types can implement (and types can implement more than one interface without conflating them with their existential type) and then providing an implicit function to automatically inject them into the context where they are used:


But as noted in my linked document above, automatic injection for Haskell doesn't play well with containers and perhaps inheritance (although perhaps that is due to other factors such as the coinductive type system).

Thus it appears to me that explicit injection via functional programming is the most modular. Is the reason I find Haskell so confusing is because it is obscuring the boilerplate in invisible implicit typing?

Did we somehow lose the plot along the way with Scala and the concept of merging functional with object oriented programming?

I don't know the answer to that question, but here is one rabbit hole I found:


My current thinking (subject to change as I learn more) is the Scala roadmap towards Dependent Object Types is appropriate because it simplifies to intersections and unions of types, which appears to me to be an unavoidable consequence of covariant and contravariant container cases. I am not clear how much of the rest of Scala is not more harmful than needed?

If the basic syntax and compiler could be radically simplified (thus hopefully must faster too), perhaps this could make Scala more appealing to a wider audience and use-cases[1]. Conceptually for the separation-of-concerns perhaps the other "features" could be done with macros operating on the AST. Appears by not modeling inheritance in DOT, this may be the conceptional direction being toyed with?

I am trying to wrap my head around what would be the idea language for programming the "web 4.0" which I visualize as unification of app programming and server programming[1]. It should be light weight, because one thing that drives many startups away from Java is the heaviness of the toolset and learning curve as compared to Javascript.

P.S. there may a lot ($millions) of money available to throw at this, if someone can elucidate the issues and optimal direction succinctly.



On Tuesday, May 12, 2015 at 4:22:59 PM UTC+8, martin wrote:
So, putting types in traits can be a
premature restriction of their usage.

The alternative to cakes is essentially functional abstraction. Have
components parameterized by others.

--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Shelby

unread,
Jul 22, 2015, 11:47:04 AM7/22/15
to scala-language
Are readers able to see the post I made on July 18 which starts with following? When viewing this thread in Google Groups, it appears to have inserted [scala-language]" into the subject line causing the start of a new thread (and other mangling of my post).

> I believe I show herein the fundamental importance of objects (as in "OOP"), that subclassing (but not subtyping)
> is fundamentally an anti-pattern, and that the new DOT calculus is essential.

Hi Vlad,

Covariance: a set of types (whether represented as a subsumption to a nominal supertype or the supertype which is a disjunction of the nominal types) can be operated on by a function which inputs that subsumption (or the set of the corresponding supersumption) or outputs the set of that subsumption (or the corresponding supersumption).

Contravariance: a set of types (whether represented as a supersumption to a nominal subtype, e.g. _|_ aka Bottom/Nothing, or the subtype which is a conjunction of the nominal types) can be operated on by a function which inputs that supersumption (or the set of the corresponding subsumption) or outputs the set of that supersumption (or the corresponding subsumption).

But how can we do any operations on a conjunction of types?

I remember Adriaan Moors explanation that in the DOT calculus a disjunction of types contains the conjunction of methods of those types (and shared methods input a conjunction of the inputs of those methods) and conversely a conjunction of types contains the disjunction of methods of those types (and shared methods input a disjunction of the inputs of those methods).

If a set of types share a set of methods (perhaps implemented as typeclass rather than virtual inheritance so the dictionary can be injected with an object), then the disjunction of those types is the conjunction (and the conjunction of those types is the disjunction) of the implementations of that interface. But note that A ∧ A = A ∨ A, so thus both disjunction and conjunction can be operated upon if they share an interface A.

That was the point of my prior post.

How does your point relate to mine?

Shelby

unread,
Jul 22, 2015, 11:51:56 AM7/22/15
to scala-language
I hate mailing lists; there is no edit feature.

Edits are in CAPS...

On Wednesday, July 22, 2015 at 11:47:04 PM UTC+8, Shelby wrote:
I remember Adriaan Moors' explanation that in the DOT calculus a disjunction of types contains the conjunction of methods of those types (and shared methods input a DISJUNCTION of the inputs of those methods) and conversely a conjunction of types contains the disjunction of methods of those types (and shared methods input a CONJUNCTION of the inputs of those methods).

Naftoli Gugenheim

unread,
Jul 23, 2015, 4:16:41 PM7/23/15
to scala-language


On Wed, Jul 22, 2015, 11:52 AM Shelby <she...@coolpage.com> wrote:

I hate mailing lists; there is no edit feature.

That's another advantage of using a blog...

Have you considered hosting a blog on github pages? It's not that hard.


Edits are in CAPS...

On Wednesday, July 22, 2015 at 11:47:04 PM UTC+8, Shelby wrote:

I remember Adriaan Moors' explanation that in the DOT calculus a disjunction of types contains the conjunction of methods of those types (and shared methods input a DISJUNCTION of the inputs of those methods) and conversely a conjunction of types contains the disjunction of methods of those types (and shared methods input a CONJUNCTION of the inputs of those methods).

Naftoli Gugenheim

unread,
Jul 23, 2015, 4:17:41 PM7/23/15
to scala-language


On Wed, Jul 22, 2015, 11:47 AM Shelby <she...@coolpage.com> wrote:

Are readers able to see the post I made on July 18 which starts with following? When viewing this thread in Google Groups, it appears to have inserted [scala-language]" into the subject line causing the start of a new thread (and other mangling of my post).

> I believe I show herein the fundamental importance of objects (as in "OOP"), that subclassing (but not subtyping)

> is fundamentally an anti-pattern, and that the new DOT calculus is essential.

Hi Vlad,

Covariance: a set of types (whether represented as a subsumption to a nominal supertype or the supertype which is a disjunction of the nominal types) can be operated on by a function which inputs that subsumption (or the set of the corresponding supersumption) or outputs the set of that subsumption (or the corresponding supersumption).

Contravariance: a set of types (whether represented as a supersumption to a nominal subtype, e.g. _|_ aka Bottom/Nothing, or the subtype which is a conjunction of the nominal types) can be operated on by a function which inputs that supersumption (or the set of the corresponding subsumption) or outputs the set of that supersumption (or the corresponding subsumption).

But how can we do any operations on a conjunction of types?

I remember Adriaan Moors explanation that in the DOT calculus a disjunction of types contains the conjunction of

methods

I believe the plan was changed later.

Have you tried using dotty?

of those types (and shared methods input a conjunction of the inputs of those methods) and conversely a conjunction of types contains the disjunction of methods of those types (and shared methods input a disjunction of the inputs of those methods).

If a set of types share a set of methods (perhaps implemented as typeclass rather than virtual inheritance so the dictionary can be injected with an object), then the disjunction of those types is the conjunction (and the conjunction of those types is the disjunction) of the implementations of that interface. But note that A ∧ A = A ∨ A, so thus both disjunction and conjunction can be operated upon if they share an interface A.

That was the point of my prior post.

How does your point relate to mine?

On Sunday, July 19, 2015 at 4:17:38 AM UTC+8, Vlad Patryshev wrote:

I would not seriously involve LSP into solving this kind of problems. LSP is for explaining things to beginners, not for solving problems in "applied category theory" (as some people call programming these days).

One of the solutions is to think about a natural transformation from a covariant functor to a contravariant functor (List[+T] => List[-T]).

Thanks,
-Vlad

Shelby

unread,
Jul 25, 2015, 1:13:13 AM7/25/15
to scala-language, she...@coolpage.com
I believe perhaps the ideas I have presented for injection of interface (relying on DOT) are a complete solution (and more generalized) to the reasons given for needing to represent family polymorphism by tracking types in the instance (which appears to be a less general form of dependency injection):

http://www.cs.au.dk/~eernst/tool11/papers/ecoop01-ernst.pdf#page=8

I will need to test and work on this idea. Okay nafg, not here in this list...

Also I discovered this interesting presentation from Martin Odersky contrasting ML modules and Scala's abstract and self types and the Cake pattern:

http://stackoverflow.com/questions/15584848/whats-the-difference-if-any-between-standard-mls-module-system-and-ocaml-mod#comment22427900_15585373

The DOT appears to be a unifying, simplifying, and generalizing concept and perhaps some past crud can be discarded.

Shelby

unread,
Jul 25, 2015, 12:11:26 PM7/25/15
to scala-language, she...@coolpage.com
On Saturday, July 25, 2015 at 1:13:13 PM UTC+8, Shelby wrote:
Also I discovered this interesting presentation from Martin Odersky contrasting ML modules and Scala's abstract and self types and the Cake pattern:

http://stackoverflow.com/questions/15584848/whats-the-difference-if-any-between-standard-mls-module-system-and-ocaml-mod#comment22427900_15585373

Can anyone explain to me the justification for the Cake pattern for the Symbol and Type relationship, instead of using a tuple parameterized on Symbol and Type assuming the two are a bijection or at least surjective?

If Symbols are not a bijection to Types, wouldn't an appropriate data structure be a collection of Symbols for each Type?

I can't fathom the re-use advantage of forcing a particular data structure with self types, as it seems to inhibit other data structures. The only relevant issue I fathom is it seems to be we need to statically insure that every instance of Symbol has created a back pointer to itself from a (collection in a) Type. The Symbol can require a method on its Type parameter which the constructor of the Symbol can invoke on its `this`. But traits aren't allow to have constructors, so we don't have a way to statically require instances of Symbol to perform the necessary operation on construction.

So it seems the Cake pattern in this case is conflating data structure re-use with invariants on the constructor, because traits have no other way to declare invariants on the constructor. If I am correct, then what could be done to improve this?

Traits don't have constructors because this would complication linearization with diamond multiple inheritance because each constructor is only supposed to be called once and so that all preconditions for each constructor are consistent. I am not sure if this could be solved with C3 linearization?

Let me assume C3 linearization is a "can of worms" w.r.t. to mixin constructors, so another idea is a syntax that declared a method of a trait as required to be invoked from the constructor. Seems to me that would be superior to conflating data structure and constructor invariants in the self type.

I hope someone will comment on this. Is they only way to do research is lonesome and without any dialogue with others. If there is a better forum for these types of discussion, please suggest to me.

Shelby

unread,
Jul 25, 2015, 12:28:53 PM7/25/15
to scala-language, she...@coolpage.com

This is yet another example of premature optimization (declaring the data structure in the self type) and my idea for a solution being an inversion-of-control, where the mixin injects a method into the constructor instead of prematuring declaring itself as a constructor.

I am starting to get the strong intuition that this concept of inversion-of-control needs to be proliferated throughout Scala 3 if we want to make a huge paradigm shift win on modularity. I am studying now the DOT calculus in detail and I am hoping I can apply such concepts so that type preservation can be recovered.

Naftoli Gugenheim

unread,
Jul 27, 2015, 2:50:36 PM7/27/15
to scala-language, she...@coolpage.com

If by "type of discussion" you mean the topic, this is a good forum to discuss it. However, while I can't speak for anyone else, I can't contribute to a discussion that I can't follow. So either you're way beyond me, and i

Naftoli Gugenheim

unread,
Jul 27, 2015, 2:50:49 PM7/27/15
to scala-language, she...@coolpage.com



If by "type of discussion" you mean the topic, this is a good forum to discuss it. However, while I can't speak for anyone else, I can't contribute to a discussion that I can't follow. So either you're way beyond me, and i


don't know how many other people, so you may need to find individuals that are interested in and up to the discussion; or it's just the way you write that's hard for me to follow, which may be due to things like unfamiliar words and the length of each email. Also it seems like you often revise your emails. So maybe it would be a good idea to first write on a blog, leaving yourself the time to edit it to your satisfaction, and once that's done, and you want to discuss it, figure out how to boil it down to something much more digestible on a mailing list.

Just my two cents, and again I'm not speaking for anyone else.



Rex Kerr

unread,
Jul 27, 2015, 3:01:26 PM7/27/15
to scala-l...@googlegroups.com, Shelby Moore
Indeed.  The emails are too much stream of consciousness, not enough tutorial with examples.  The latter are really necessary to clarify thinking--often they will help clarify your own thinking as under-examined issues tend to come up when you force yourself to make a fully-working example with all steps explained at least in brief.

A blog is probably a better venue.  (Or if you want to develop theory, you could use a GitHub repository, so you can gradually change and extend the reasoning and examples with good tools for looking at the history, etc..)

  --Rex

Som Snytt

unread,
Jul 27, 2015, 3:05:27 PM7/27/15
to scala-l...@googlegroups.com, Shelby Moore
> The emails are too much stream of consciousness

It would help if you upgraded to Reactive Streams of Consciousness. Then you could handle the backpressure.

Shelby

unread,
Aug 20, 2015, 3:42:31 PM8/20/15
to scala-language, she...@coolpage.com
Thanks nafg, Vlad, Rex, some-snytt, et al.

I will come back to this asap and with proper organization. I was in an extreme rush and just wanted to get my first thoughts recorded some where they might be seen. I especially wanted to get that summary post into the Scala Roadmap thread, because I am concerned that DOT and Dotty need some radical tweak yet before we go that direction. All the progress is great, but I think by not discarding subclassing and replacing it with my proposal for compiler assisted inversion-of-control (assuming it can't be otherwise unified from some other perspective such as category theory), then we will have lost a critical opportunity to be the next mainstream language that overtakes Java finally.

I recently watched the video of Martin's presentation from Scaladays 2015 and I really love the TASTY direction to modularize orthogonal compilation layers. Kudos!

And I love the conceptual idea of simplification via unification (paradigm shift) in DOT. I just think we will miss a huge opportunity if we don't deprecate subclassing for Scala 3. If we love at the popular languages, it is Java #1 but on a steady decline (perhaps Android and Java 8 staved off a free fall for a short while) and all these FP languages as nipping at its heels, e.g. Scala, Clojure, Python, etc..

Scala needs to be cleaned up and even less verbose. Eliminating subclassing can enable the DOT calculus to become much simpler and also enable more opportunities to infer types to reduce verbosity.

IMO what has prevented an FP language from overtaking Java is the lack of mainstream need for any particular feature of FP, as well as it being presented a bit too obtusely. Scala made some leaps forward on being less obtuse because it looks more like a familiar OOP language, eager evaluation by default, non-total by default, etc.. But the most salient point IMHO, is there is no requirement to use typing in programming. People can make arguments either for and against static typing.

But I think I have shown (and I understand I need to organize my presentation and thoughts soon) that no one can get fine grained extensibility without refactoring and recompilation without my idea for inversion-of-control which requires the sophisticated and unified typing of DOT (sans the subclassing).

Even if Scala's community doesn't want to make my idea the main direction, I hope I can experiment and present as a side effort.

I'll try to get organized before the final commitment to current DOT has too much momentum. I am racing right now on other project first.

Apologies for cluttering the list with my stream of consciousness posts.

On Tuesday, July 28, 2015 at 3:01:26 AM UTC+8, Rex Kerr wrote:

Shelby

unread,
Aug 21, 2015, 5:03:42 PM8/21/15
to scala-language, she...@coolpage.com
I have two reasons to sort of break my implied promise in my prior message that I would come back when organized.

1. I have been in an ongoing discussion with a senior software developer as follows below, who is an expert Java programmer, who favors Lisp as his favorite language, and who a polygot in computer languages. So the following summary may need to be revised on further clarifications from that person. But I think it will remain true that it serves as a poignant insight into why Scala can never become a mainstream language UNLESS IT MAKES THE ARGUMENT ABOUT STATIC TYPING LESS SUBJECTIVE. I think if we show that subclassing can be replaced with a compiler assisted inversion-of-control for a complete solution to Wadler's Expression Problem, such that we hardly never need to refactor and recompile again, modules get smaller and more orthogonal, and much of the tsuris of programming falls away, then we can finally slam dunk the Steve Yeggies of this world. Of course dynamically (uni-)typed languages will always have a role to play. The point is to attempt to elucidate clear victories for expressive typing that are not as nebulous as arguments up to now. Many programmers do not internalize the fact that the semantics of code always have types, but if your compiler can't express these types then you cast them away and instead model your invariants with comments, in your head, and regression testing. But regression testing tests effects, not invariants. In the Scala Days 2015 presentation, Martin Odersky attempted to make this point in slide 10 (link below), but I think the point needs to be made more emphatically that expressive type systems are about capturing the types that are already in your program. Wadler made the point when distinguishing between S-modularity and I-modularity in the following linked blog comment (note it immediately followed my comment):


2. Help! I know we aren't supposed to advertize jobs on the mailing lists but I can't operate through normal job finding avenues because the controlling group and investors in the project I refer to are anonymous thus only pay in Bitcoin (job sites do not accept Bitcoin and anonymous employers even to get started). I am very handicapped in trying to make Scala the reality for this coin. I wish I could find a Scala developer interested in helping me make sure a radically innovative altcoin has a Scala ecosystem and not Java or C. It could be a major win for Scala because it could spawn many network effects Scala projects. I am available via private message on the Bitcointalk forum. Also the profit potential is unfathomably large (as is the risk of failure). I suggest going to the linked posts below and reviewing the description of advantages over Bitcoin.

https://bitcointalk.org/index.php?topic=1049048.msg12200924#msg12200924  (the post quote below)

[quote=myself a.k.a. TPTB_need_war]
In other news, a very prominent member of these forums who claims he is a world-class programmer has expressed strong interest in partnering with me to help me get this implemented faster (which I very much appreciate). We are in discussions, but this may or may not work out because we have a (slight or significant?) difference of opinion on the preferred computer language and potentially his cash compensation opportunity cost may be too high (or maybe not, as I haven't seen his figures yet). And there is unclear communication (so far) about the importance of modularity. As best as I can determine thus far, he prioritizes very much speed of implementation at the cost of expressive type systems that [i]some claim[/i] (which he may have a right to doubt and others do doubt) can capture modularity in a way that eliminates much of the [url=http://accu.org/content/conf2009/ACCU2009_Bernhard_Merkle_StopTheSoftwareArchitectureErosion.pdf#page=17]metastasizing spaghetti code[/url] because he said for as long it is all open source, his point is you can always refactor and recompile. Whereas, I believe modularity is a paramount priority and that one can be just as productive by following "best coding practices" (and that is a subjective phrase to some extent so my "best" could be argued as not "best" by others). As far as I can grasp so far, this person claims all that theoretical computer science doesn't matter that much (or slows us down when it is not yet a mainstream language or most other programmers won't take to it) and he claims he is very productive regardless. I have no doubt he is productive in the short-run, but I am concerned about [url=http://accu.org/content/conf2009/ACCU2009_Bernhard_Merkle_StopTheSoftwareArchitectureErosion.pdf#page=17]metastasizing tightly coupled spaghetti over the long-term[/url] as a project becomes more ingrained and complex. His perspective is not without merit but it is the sort of comment you hear from folks who are trying to justify why dynamically typed languages should be used every where, e.g. [url=http://steve-yegge.blogspot.com/2008/06/rhinos-and-tigers.html]Steve Yeggie[/url] and even the [url=http://jobtipsforgeeks.com/2012/05/17/lessons-from-a-jug-talk-with-eric-esr-raymond/]progenitor of the term "open source" the 150+ IQ genius Eric S. Raymond[/url]. And although it is a reasonable point to balance, it is not an absolute truth and there are good reasons sometimes to think the other way. Most programmers can do more damage to your project than you initially realize (although I suspect that doesn't apply to the programmer I am referring to above). However criticizing myself, one has to be pragmatic and accept that the productivity of even sufficiently large numbers of monkeys (not the programmer referred to above) banging randomly on source code can find (and [url=http://www.technologyreview.com/news/506466/given-tablets-but-no-teachers-ethiopian-children-teach-themselves/]even fix[/url]!) more bugs than one guy lonesome.

[/quote]

Slightly edited salient portion of my prior message follows...

On Friday, August 21, 2015 at 3:42:31 AM UTC+8, Shelby wrote: 
... because I am concerned that DOT and Dotty need some radical tweak yet before we go that direction. All the progress is great, but I think by not discarding subclassing and replacing it with my proposal for compiler assisted inversion-of-control (assuming it can't be otherwise unified from some other perspective such as category theory), then we will have lost a critical opportunity to be the next mainstream language that overtakes Java finally.


I recently watched the video of Martin's presentation from Scaladays 2015 and I really love the TASTY direction to modularize orthogonal compilation layers. Kudos!

And I love the conceptual idea of simplification via unification (paradigm shift) in DOT. I just think we will miss a huge opportunity if we don't deprecate subclassing for Scala 3. If we look at the popular languages, it is Java #1 but on a steady decline (perhaps Android and Java 8 staved off a free fall for a short while) and all these FP languages as nipping at its heels, e.g. Scala, Clojure, Python, etc..


Scala needs to be cleaned up and even less verbose. Eliminating subclassing can enable the DOT calculus to become much simpler and also enable more opportunities to infer types to reduce verbosity.

IMO what has prevented an FP language from overtaking Java is the lack of mainstream need for any particular feature of FP, as well as it being presented a bit too obtusely. Scala made some leaps forward on being less obtuse because it looks more like a familiar OOP language, eager evaluation by default, non-total by default, etc.. But the most salient point IMHO, is there is no requirement to use typing in programming. People can make arguments either for and against static typing.

But I think I have shown (and I understand I need to organize my presentation and thoughts soon) that no one can get fine grained extensibility (that is without refactoring and recompilation) without my idea for inversion-of-control which requires the sophisticated and unified typing of DOT (sans the subclassing).

Naftoli Gugenheim

unread,
Aug 21, 2015, 6:08:54 PM8/21/15
to scala-language, she...@coolpage.com


On Fri, Aug 21, 2015, 5:03 PM Shelby <she...@coolpage.com> wrote:

I have two reasons to sort of break my implied promise in my prior message that I would come back when organized.

1. I have been in an ongoing discussion with a senior software developer as follows below, who is an expert Java programmer, who favors Lisp as his favorite language, and who a polygot in computer languages. So the following summary may need to be revised on further clarifications from that person. But I think it will remain true that it serves as a poignant insight into why Scala can never become a mainstream

language

Wait, it hasn't already?

Shelby

unread,
Aug 21, 2015, 8:38:41 PM8/21/15
to scala-language, she...@coolpage.com
Appears to be about 2.5% of Java's popularity. And the retort I get is that most developers will leave immediately after seeing you've chosen Scala.

I retorted that choosing Scala is choosing a culture that prioritizes modularity and separation-of-concerns over monkey patching. And thus a useful filter.

But he has a point. He is expert in Java and I can't find a Scala programmer to help me. And he is available and motivated to code in Java, but not in Scala.

I read articles that say it is very difficult to find a Scala programmer, because they are in such high demand and already have interesting projects they are working on. Hey I am just a geek, not a human resources manager.

Shelby

unread,
Aug 21, 2015, 9:05:23 PM8/21/15
to scala-language, she...@coolpage.com
I agreed with all the range of discussion at the following HN thread. In particular, I want to call attention to the following post which emphasizes that Scala is not sufficiently simplified and unified. Scala 3 with the DOT (Dotty) proposal is attempting to make some headway, and my position is to try to remove subclassing (retain subtyping) and replace with a superior paradigm which is more unified, which will make the calculus more provable, will make type inference more simplifed and complete, and will remove the CAKE pattern and other warts which are giving Scala a bad rap while also slam dunking it to massive adoption...


This might be worth a read:
http://codahale.com/the-rest-of-the-story/
http://codahale.com/downloads/email-to-donald.txt
Having worked with Scala; I'd say I love it.
Having worked with Scala; I'd say don't use it for most projects.
It is not the best language to start learning FP. Wrap your head around a dedicated FP language and if you still feel the need for a hybrid FP/OO language Scala is definitely worth a look.
However as it is a hybrid I've felt it made my code just too complex. Compared to Java there are a dozen more ways in Scala to fix something; and often you struggle to find the best way. This takes a lot of learning and it just isn't worth it. It's a great and elegant language in many ways, but I've come to dislike a lot of features of it.
Simplicity is one of those things that make a beautiful codebase. See also (recently featured on HN)


Raoul Duke

unread,
Aug 22, 2015, 12:25:12 AM8/22/15
to scala-l...@googlegroups.com
re: subtyping: LSP always seems a bit restrictive/subjective to me, so
I wonder if sub-anything is really to be desired in the long run.

Simon Schäfer

unread,
Aug 22, 2015, 5:13:25 AM8/22/15
to scala-l...@googlegroups.com


On 08/22/2015 03:05 AM, Shelby wrote:
> I agreed with all the range of discussion at the following HN thread.
> In particular, I want to call attention to the following post which
> emphasizes that Scala is not sufficiently simplified and unified.
> Scala 3 with the DOT (Dotty) proposal is attempting to make some
> headway, and my position is to try to remove subclassing (retain
> subtyping) and replace with a superior paradigm which is more unified,
> which will make the calculus more provable, will make type inference
> more simplifed and complete, and will remove the CAKE pattern and
> other warts which are giving Scala a bad rap while also slam dunking
> it to massive adoption...
If you want to convince anyone that subclassing should be replaced by
something else you should first start by explaining what this new
concept of yours is. I'm interested in understanding your new concept
but between all of the posts you wrote and links you posted I'm just not
able to understand anything you wrote anymore. And I'm too lazy to
reread everything in hope to get a better understand. It would be time
to write something that has a structure similar to a paper, otherwise
there aren't many which may consider your thinkings.

Shelby

unread,
Aug 22, 2015, 6:03:58 AM8/22/15
to scala-language
Will do asap. My high priority todo is backlogged. I think before 2006 I would have been faster, but I'm suffering from Multiple Sclerosis. On a new experiment past 36 hours, eating only leafy greens, 2 egg yokes daily, and the white meat of the coconut to try to keep my body in ketogenesis. So far, this is causing me to sleep most of the time, so I am losing so many productive hours to this condition.

Bardur Arantsson

unread,
Aug 22, 2015, 6:43:53 AM8/22/15
to scala-l...@googlegroups.com
On 08/22/2015 03:05 AM, Shelby wrote:
> I agreed with all the range of discussion at the following HN thread. In
> particular, I want to call attention to the following post which emphasizes
> that Scala is not sufficiently simplified and unified. Scala 3 with the DOT
> (Dotty) proposal is attempting to make some headway, and my position is to
> try to remove subclassing (retain subtyping) and replace with a superior
> paradigm which is more unified, which will make the calculus more provable,
> will make type inference more simplifed and complete, and will remove the
> CAKE pattern and other warts which are giving Scala a bad rap while also
> slam dunking it to massive adoption...
>

I think you're tilting at windmills. As I understand it, part of the
raison d'être of Scala is that it is a research vehicle[1] and that "how
to do subclassing right" is/was a big part of that research. Instead of
tilting, perhaps you should look into some of the more... ahem...
polished functional languages? Like O'Caml or Haskell?

For example, it seems that much of what you want is already provided by
the row polymorphism support in O'Caml...? (Btw, O'Caml also has an
object system which is structural, i.e. non-nominal, but ironically --
given the name of the language -- almost nobody used it last I heard...
which was quite a long while ago, admittedly.)

Regards,

[1] Well, at least it started out that way. I guess things might have
changed?

Shelby

unread,
Aug 22, 2015, 1:26:40 PM8/22/15
to scala-language
It seems Haskell has trouble with the fact that it doesn't do subtyping for example the type a list when it is a conjunction of types in the list. I wish I was more expert with Haskell so I could better comprehend the ways Haskell works around this.

Shelby

unread,
Aug 22, 2015, 1:33:47 PM8/22/15
to scala-language, sp...@scientician.net
Thanks I'll try to look at that. I don't know ML well and struggle with its syntax so it will slow me down, but I should see if that does already provide the functionality. Necessary of course for writing a white paper and citing prior art.

Even then there are other variables at play such as:

* tool support
* JVM interopt
* JS compilation (I must have this!)
* fugly syntax of OCaml (imo)
* community
* momentum

I believe Scala heads can be convinced subclassing is an anti-pattern but even if not, it appears Scala is headed towards being a modular platform for language experimentation with the move towards a TASTY layer.

I sense that Scala will be the place where there economies-of-scale form. Maybe not. Need to consider a lot of details and I am 1000 miles up in the air right now due to other priorities.

Shelby

unread,
Aug 23, 2015, 10:58:04 AM8/23/15
to scala-language, sp...@scientician.net
I am in the midst of studying OCaml in case it should be a preferred language choice for the project I am currently launching. The curiosity is unbearable.

First gripe (and attempting to make the first case of justification for my allegation of "fugly syntax") is I want to know how many in the Scala community agree or disagree with my preference for parens around function operands (a.k.a. parameters or arguments)? Those coming from the C, C++, and Java background do not usually like the FP preference of just using spaces. My justification on top of that legacy, popularity point is that without parens, you must visit the function declaration site before you can read the function use site. For someone unfamiliar trying to read code, this places a burden of "all or nothing" knowledge of the source code, which is highly inefficient and not in the spirit of separation-of-concerns and single-point-of-truth. The only place where I think spaces should be allowed are for infix operators (even those which are keywords instead of symbols), i.e. those in which there is an operand on each side of the operator, and those unary (post or prefix) operators which are symbols (and in that case there should be no spaces between the operand and operator, use parens if you need to juxtapose unary operators). These are the sort of rules that I would like to see so there is consistency to Scala code because given open source "the #1 priority of any programming language bar none, is readability"— Eric S. Raymond the progenitor of the term "open source":

http://jobtipsforgeeks.com/2012/05/17/lessons-from-a-jug-talk-with-eric-esr-raymond/

So that is one way Scala can differentiate itself from other purest, snobbish FP languages and be more friendly to those coming from mainstream backgrounds.

Feedback?

John Nilsson

unread,
Aug 23, 2015, 12:11:59 PM8/23/15
to scala-language, sp...@scientician.net
With regards to parameter lists I think there is a case to be made for not treating not them as lists at all. The order is usually not important, while the name of the binding is. So it's probably better to treat arguments as a set of bindings or as first class environments.

The names of the argument needs to be explicit in the type to allow disambiguation, and also to support overloading on parameter name only (if the type of the value is not sufficient)

Also, when the parameter order is not significant composition and application can be commutative.

BR
John


John Nilsson

unread,
Aug 23, 2015, 12:47:48 PM8/23/15
to scala-language, sp...@scientician.net
To expand on that last part a bit.

In FP languages like Haskell you have functions to be unary, with partial application and higher order return types to support multi parameters.
X->Y->Z apply X = Y->Z
In language like scala, which also focuses on objects it seems prudent to have objects for parameters.
{x:X}->{y:Y}->{z:Z} apply {x:X} = {y:Y}->{z:Z}
But since we now have the bindings lets just simplify to
{x:X,y:Y}->{z:Z} apply {x:X} = {y:Y}->{z:Z}
Since the order is now not important
{a:A}->{y:Y} andThen {x:X,y:Y}->{z:Z} is simple enough
BR
John.



Shelby

unread,
Aug 23, 2015, 2:42:47 PM8/23/15
to scala-language, sp...@scientician.net
I assume you meant {a:A}->{y:Y} composed with {x:X,y:Y}->{z:Z} is {x:X,a:A}->{z:Z}

If I am not mistaken, it appears you are stating objects should be structurally typed instead of nominal. Afair, the new DOT has some issue with structural types? But here you are only using the structurally typed object in the context of the function parameters, so perhaps that is a mitigating factor.

Scala added named parameters in 2.8. Is the only difference from your idea the use of parens versus braces? Or is the difference around the use of named parameters under application and composition?

Shelby

unread,
Aug 23, 2015, 3:05:10 PM8/23/15
to scala-language, sp...@scientician.net
One issue I see with obligatory (versus optional) named parameters, is I really wish Scala could do OCaml's (tuple and any other unapply) destructing on the function parameters:

# let distance (x1,y1) (x2,y2) =
    sqrt ((x1 -. x2) ** 2. +. (y1 -. y2) ** 2.)

So in Scala:

def distance((x1,y1), (x2,y2)) = ...

And why can't Scala infer those types given sqrt inputs Float? One of the big complaints I hear is Scala can't infer types.

Or at least why do I have to redeclare the types in a class that implements a trait where the types where already declared in the trait and there is no ambiguity?

P.S. in our second post you pointed out that a function with more than one parameter is a unary function under application and a function with more than two parameters is an infix function under application, so I need to think about how that meshes with my idea about only allowing unary and infix functions to use spaces instead of parens.

Simon Schäfer

unread,
Aug 23, 2015, 4:06:03 PM8/23/15
to scala-l...@googlegroups.com


On 08/23/2015 09:05 PM, Shelby wrote:
One issue I see with obligatory (versus optional) named parameters, is I really wish Scala could do OCaml's (tuple and any other unapply) destructing on the function parameters:

# let distance (x1,y1) (x2,y2) =
    sqrt ((x1 -. x2) ** 2. +. (y1 -. y2) ** 2.)

So in Scala:

def distance((x1,y1), (x2,y2)) = ...

And why can't Scala infer those types given sqrt inputs Float? One of the big complaints I hear is Scala can't infer types.

This is a complaint mostly by Haskell people or people doing lots of functional programming in general. Beside from a few cases I don't see this as very important. You don't want to have inferred argument types in public methods for any nontrivial project.



Or at least why do I have to redeclare the types in a class that implements a trait where the types where already declared in the trait and there is no ambiguity?
You don't have to:

% s -Yinfer-argument-types
Welcome to Scala version 2.11.7 (OpenJDK 64-Bit Server VM, Java 1.7.0_85).
Type in expressions to have them evaluated.
Type :help for more information.

scala> trait T { def f(i: Int) = i }
defined trait T

scala> trait TT extends T { override def f(i) = i }
defined trait TT

Shelby

unread,
Aug 23, 2015, 5:38:39 PM8/23/15
to scala-language


On Monday, August 24, 2015 at 4:06:03 AM UTC+8, Simon Schäfer wrote:


On 08/23/2015 09:05 PM, Shelby wrote:
One issue I see with obligatory (versus optional) named parameters, is I really wish Scala could do OCaml's (tuple and any other unapply) destructing on the function parameters:

# let distance (x1,y1) (x2,y2) =
    sqrt ((x1 -. x2) ** 2. +. (y1 -. y2) ** 2.)

So in Scala:

def distance((x1,y1), (x2,y2)) = ...

And why can't Scala infer those types given sqrt inputs Float? One of the big complaints I hear is Scala can't infer types.

This is a complaint mostly by Haskell people or people doing lots of functional programming in general. Beside from a few cases I don't see this as very important. You don't want to have inferred argument types in public methods for any nontrivial project.


Actually I agree on public methods exposed outside the "module". And to document your APIs as well. But afaik there are cases of 'public' methods not exposed to the public and more emphatically many cases of local functions where you don't want to write all that noisy boilerplate.

 



Or at least why do I have to redeclare the types in a class that implements a trait where the types where already declared in the trait and there is no ambiguity?
You don't have to:

% s -Yinfer-argument-types
Welcome to Scala version 2.11.7 (OpenJDK 64-Bit Server VM, Java 1.7.0_85).
Type in expressions to have them evaluated.
Type :help for more information.

scala> trait T { def f(i: Int) = i }
defined trait T

scala> trait TT extends T { override def f(i) = i }
defined trait TT

Well I thought I had tried in the past and received an error. I don't have a Scala installation on this computer (I'm at a different location) so I tried to access SimplyScala but it is down. On scala-js-fiddle.com your code does not compile unless I declare the type of the i parameter.

Naughty you using a subclassing example when you didn't need to make your point ;)

John Nilsson

unread,
Aug 23, 2015, 6:13:39 PM8/23/15
to scala-l...@googlegroups.com, sp...@scientician.net
I guess I'm not sure about nominal vs structural. If you tilt your head enough you could view methods as classes, such that the method name as such is the class name. Which gets you thinking of inheritance at method level. What would it mean for a def to extend another def? But yes, I was essentially thinking of parameter lists as structurally typed. In the interest of simplifying I'm thinking that it would be a path towards unifying tuples, structure types and argument lists.
If you tilt your head in the other direction you can see objects and parameter lists as interpreter composition. Inside the method is an expression, and it is interpreted in the environment of the object augmented with the environment from the parameters. Nominal types gets somewhat in the way here as you want composition and (partial) application to reduce to simpler types, which seems easier with structural types.
Regarding, syntax. The braces was just meant to convey the nature of a set rather than a list. Not really a suggestion for actual Scalia syntax. The real difference is the removal of parameter order from the semantics of he language, but also that I want to decouple the argument set from the method to allow direct manipulation of it, not necessarily in the same context as the method.
BR,
John

Shelby

unread,
Aug 23, 2015, 8:42:09 PM8/23/15
to scala-language, sp...@scientician.net
Okay I think I learned enough OCaml to understand row polymorphism for objects. Warning potential Dunning-Kruger statements ahead...

Afaics, it doesn't apply to the scenario of the Expression Problem I was addressing.

It appears row polymorphism is a way of declaring you want access to specific methods by name (structural typing) regardless of any other methods present in the object. But that is still requiring the control to be in the objects.

I was trying to solve the Expression Problem cases where the control can't be in the objects, and the control needs to be inverted and injected orthogonal to the objects. Not to mention that my proposal is agnostic to whether nominal or structural typing is employed.

For example, a function inputs a collection (e.g. a List) of objects but the caller has a List of objects which don't have the same type but there exists a way to pimp them to the required type. Do you create an entirely new list by wrapping all those objects as pimped. How inefficient. Instead we want that first function to input an injected interface as an extra function parameter, and this interface accepts as "this" the polymorphic type of the objects in the collection parameter. I gave coding examples previously and I will try to organize it all in near future.

Thus subclassing is no longer needed for implementing polymorphism because if you want reimplement a method of another type, provide a conversion from that type to your type.

I have now realized that an implicit function parameter (as the recommended replacement for the deprecated view bounds) can accomplish a large chunk of what I wanted.

First-class conjunctions (and disjunctions) are absolutely necessary because the implicit function parameter can't be a conversion from Any to the required type. For my idea to work we can't discard the types by subsuming to Any.

But it is wonderful to now realize that Dotty already supports my vision. All that remains is a deprecating subclassing and then realizing the gains in simplification of the DOT calculus so it is provable by traditional methods, and I think this will also make type inference more robust if I am not mistaken.

There may be other aspects of my original ramblings that are not incorporated into what I wrote in this post. I will need to review (preferably when I am not 4 days into fasting).


<rant>Of the many things I hate about OCaml's syntax is that it does everything snobbishly different from C, C++, Java heritage of the mainstream, e.g. semicolons as separator just afaik because they wanted to use commas for tuples and wanted to allow tuples to be written with or w/o enclosing parens, (* comments *), 2. +. 1., and other gnarly "symbol soup" bewilderment. Perhaps that's all necessary to make global type inference work seamlessly.</rant>




On Sunday, August 23, 2015 at 1:33:47 AM UTC+8, Shelby wrote:

David Starner

unread,
Aug 24, 2015, 1:11:00 AM8/24/15
to scala-l...@googlegroups.com
On Sun, Aug 23, 2015 at 5:42 PM Shelby <she...@coolpage.com> wrote:
<rant>Of the many things I hate about OCaml's syntax is that it does everything snobbishly different from C, C++, Java heritage of the mainstream, e.g. semicolons as separator just afaik because they wanted to use commas for tuples and wanted to allow tuples to be written with or w/o enclosing parens, (* comments *), 2. +. 1., and other gnarly "symbol soup" bewilderment. Perhaps that's all necessary to make global type inference work seamlessly.</rant>


ML came out in the early 1970s and would have been well formed by the time that C escaped from Bell Labs. Even then, until Java and Javascript came along, C syntax was confined to C and its dialects and Awk. It seems a little silly to call a language snobbish for not throwing away 20 years of tradition when Java came out and not changing syntax to match an entirely alien language.

Raoul Duke

unread,
Aug 24, 2015, 1:20:24 AM8/24/15
to scala-l...@googlegroups.com
> It appears row polymorphism is a way of declaring you want access to
> specific methods by name (structural typing) regardless of any other methods
> present in the object.

yeah, to me the term reads as a confusing way to say "structural types". :-}

Raoul Duke

unread,
Aug 24, 2015, 1:24:07 AM8/24/15
to scala-l...@googlegroups.com
> I was trying to solve the Expression Problem cases where the control can't
> be in the objects, and the control needs to be inverted and injected
> orthogonal to the objects. Not to mention that my proposal is agnostic to
> whether nominal or structural typing is employed.

"extension methods" a la C# and many other languages rub me the wrong
way. They are either:

(a) proof that OO quickly sucks and we shouldn't have started with
that crap in the first place!

or,

(b) proof that people don't effing know how to / have the intestinal
fortitude to ACTUALLY DO OO for realz.

either way, i hate everything. ;-)

martin odersky

unread,
Aug 24, 2015, 3:19:06 AM8/24/15
to scala-l...@googlegroups.com, scala-debate
Please, everyone, take the discussion to scala-debate. This has
strayed too far from the topic of scala-language.

Thanks

- Martin
> --
> You received this message because you are subscribed to the Google Groups "scala-language" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Martin Odersky
EPFL
Reply all
Reply to author
Forward
0 new messages