-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Afaics N4JS has no compelling market #266
Comments
PureScript doesn't really force purity, it just supports monad syntax extensions. Async IO in JS already forces "monadic code" (with sugar equivalent to do syntax). Sounds like PureScript is a better starting point for you? |
@spion write:
Use site syntaxHow can it be a starting point when it doesn't even use parenthesis to tuple the function arguments as JavaScript and C-like languages do? That is so foreign to me, because it requires I know how many arguments each function takes at the declaration site, in order to read the usage of the use site. Although I could write all function applications surrounding with parenthesis, e.g. Global type inferencePureScript apparently has global type interface, which I explained to before, afaik prevents implementation of a typeclass in more than one way.
In Haskell, an That is is unacceptable to me and besides I want to declare types on public functions and methods because it maintains binary compatibility of the API when incidental refactoring are done (which in global inference can cause a cascade of inferred type changes every where), which is essential for separate compilation modularity. Haskell (and thus apparently PureScript) breaks all these. No Anonymous (Structural) UnionsPureScript has product and sum types, but they are nominal. The inference engine can't create an anonymous structural sum type (union) in order to model for example the fact that the logical (to be continued, I'm having a flare-up of my autoimmune illness and thus am temporarily unable to read...) PureScript's |
The PureScript community is somewhat interested in working on modular typeclasses / modular implicits. Another option that fits your requirements better is BuckleScript, a clean ocaml-to-js compiler. OCaml are working on adding modular implicits to the mainline language already. |
TLDR;@shelby3 thanks for your intrest in N4JS. It would be nice if you would use our language in your project. If you decide not to, we would appriciate to share reasoons why. This would be valuabe input to design of the N4JS. Still, it seems impossible to design any non trivial project, like programming language and dedicated tooling, to everyones individual liking. The Rant.Meta: I would like comment on few things you have mentioned. "N4JS has no compelling market"As for N4JS market this is twofold topic. Now from the language site JavaScript is the best language for external developers to contribute to our platform but we needed important features (...) and that's why we developed N4JS to provide these missing features. So if the number of apps available is supposed to grow, possibly in cooperation with partners, and even external developers, than it makes sense for N4JS to be publicly available. We want the best experience for people working on our platform, regardless if it is internal developer, or... you. If N4JS would be the only thing we do, and if our goal would be only to replace TypeScript/PureSecript/VanillaJS/(insert your favourite compile to JS language) then it would be a challenge (i.e. questionable product idea). But it is not the case. Note, that it is not uncommon. Take FlowType by Facebook as an example. I am sure it helps them with their platform. They made it publicly available, so anyone can use it for their project. I don't know what 'market share' it has in JS landscape. I assume not so big, still it made sense for them to make it public, still people use it in their non Facebook related projects. "why I or anyone would to use N4JS instead of GWT"?GWT is interesting example, we have used GWT internally for some time (~3-4 years or so), but that approach had it drawbacks for us. Issues with modifying type checking or inference, type declarations in comments, maintenance of our extensions/modifications across different GWT releases, building tooling (i.e. IDE) on top of that without proper APIs... at some point it stopped making sense for us. We could have switch to something else like mentioned FlowType, Scala.js or something else but that approach would have the similar problems. "doesn't offer everything is an expression"That is nice feature, but as TypeScript developers answered that is not in JS, and adding that would violate their design goals. "too many paradigms"That is unfortunate case of many languages. "The emitted JS is somewhat incomprehensible in the browser's JS debugger"There is a lot of effort on our side to avoid that. We emit JS that is debuggable in the browser. On top of that we emit source maps, to allow you debug N4JS directly in the browser. There is some amount of 'noise' that cannot be removed now (until certain JS features are widely supported) or without the tradeoff (loosing backwards compatibility) or without cutting some features (like some reflection api). "I'm forced to use an IDE even for simple scripts"Well, no. For any language that is not based on projectional editor (i.e. does not include elements that are not within ASCII/Unicode/etc.) you can use text editor of your choice. As long as you can type it in some text editor, you don't have to use any "IDE". On few occasions I was editing N4JS in the browser directly on GitHub. As long as there is some compiler (i.e. text parser + other parts) to process your code, you can use any text editor. "It doesn't have typeclasses and I now think subclassing is an anti-pattern"I am not sure if there are OO languages that have type classes, it seems to be more Functional Programming thing. It is interesting question where JS stands? It is functional, but everything is an object and now it has classes. Maybe it is "too many paradigms", but lets leave theoretic discussion aside. If you don't like class based inheritance, don't use it. Composition and delegation over inheritance. Use interfaces to define types. In your classes implement multiple interfaces but don't declare superclasses. This way you have no class inheritance, but you get type composition. If you need instances of the same class to use different method implementation, parametrise delegation. Look at emulating type classes in F# "emulates Java's lack of brevity"Well that is a bit unfair, in the end we don't do this on purpose. Everything has to be written down, except things that can be somehow deduced. Type inference allows to skip type declaration, default access modifiers allow to skip access declaration, etc. We will improve type inference, but there will be places where you have to declare some types. Maybe default access modifier should be 'public', I personally like that idea. "forces me into the Java ecosystem of IDEs and even the source code of N4JS has many Java dependencies"No and yes.
"it must be a self-hosted compiler asap, and it should not have any dependencies which are not self-hosted"Well, self bootstrapping is not absolute "holly grail". Not everyone agrees with that. P.S.Wow, that was a long rant. P.S.S.It would be a hassle to rename language now, but please propose more marketable/brandable name. For a good name it might be worth to do it. |
@yoosiba thanks for the reply. You have some good points which I roughly agree with, and I will respond on those in more detail later. For now, I want to emphasize the most important point. Specialty (novelty) programming languages with small ecosystems die because nobody wants to invest their man-hours in a syntax that will become orphaned. Thus I am thinking you need to make your language popular enough that the open source resources will come in to refine and maintain it. For that goal to be achieved, I am going to strongly suggest you implement typeclasses cleanly and elegantly, so that you have a competitive advantage that NO OTHER PROGRAMMING LANGUAGE has. There is no strict evaluation, optimally targeted to JavaScript, with structural first-class unions, and typeclasses language on earth right now. The closest is PureScript, which has several flaws making it unsuitable for those who want to write in a syntax and semantics as close to EMCAScript as possible while gaining the best typing advantages. I want to convince that I believe that typeclasses may be the "killer feature". Apple's Swift has implemented them (sort of) and is leading the way. Rust has adopted them but conflated it with other paradigms (global lifetimes tracking) which are unsuitable to the mass market. I believe typeclasses are going to be the next big hot language feature, because they enable extensibility on both axis of Wadler's famous Expression Problem. Please read my TypeScript Issue thread which explains typeclasses in great detail. I think if N4JS were show willingness to implement typeclasses, I would likely throw all my support effort to N4JS. I can't speak for @keean (he is a CTO in the UK and co-author of HList paradigm), but I have invited him to this thread. I will be brainstorming on language names. I am not trying to push you to do anything. I just hope you will feedback to me why and what fits and doesn't fit your strategies. I am trying to decide what I should do. Do I have to go write my own language? I hope not. Note the above is an oversimplification. Many details need to be looked at. I need to better understand your goals and rules in terms of what you will and won't add to your language. I need to better understand where the feature set of N4JS is now and the rate of progress. I need to better understand if I would be able to quickly come up to speed on the contributing to the development of N4JS and in what areas of the project. So the above is just to elicit any off-the-cuff feedback or discussion you would like to enjoin. |
This discussion is broader than just type classes. You might want to create separate feature request for that purpose only.
This might delay projects in which you intend to use language with type classes ;) BTW, below is N4JS version of the code proposed by @keean in the TS thread interface Identifable {
as_string() : string
}
interface ICar extends Identifable {
revision :string
@Override as_string() : string {
return this.revision
}
}
interface IAnimal extends Identifable {
species :string
@Override as_string() : string {
return this.species
}
}
interface IDog extends Identifable, IAnimal {
breed :string
@Override species = 'mammal';
@Override as_string() : string {
return this.breed
}
}
class Car implements ICar { @Override revision = 'caddy'; }
class Animal implements IAnimal{ @Override species = 'not only mammal'; }
class Dog implements IDog { @Override breed: string = 'pomeranian'; }
function <T extends Identifable> logIdentity(x : Array<T>) {
x.forEach(element => console.log(element.as_string()))
}
let all :Array<Identifable> = [new Car(), new Dog(), new Animal()];
logIdentity(all);
interface ICat extends Identifable {
name :string
@Override as_string() : string {
return this.name
}
}
class MyCat implements ICat{
@Override name : string = "Widget"
}
all.push(new MyCat());
logIdentity(all); |
I am sure you realise but the above code lacks the extensibility of the code I posted. With the type-class examples any of the objects (say MyCat) can be extended to incorporate new behaviour without rewriting the class or interface definitions. This can be done by implementing an interface on an existing type, even a primitive type. |
@yoosiba with your design pattern, if we defined a new trait interface, we wouldn't be able to implement Typeclasses are a very exceptional advancement over subclassing. Subclassing is really rigormortis refactoring hell (which is probably why you need those superfluous noisy Edit: it wasn't my intention to write the above with any implied blame. I was suffering a health ailment while writing the above and simply wasn't able to filter my words for congeniality. My intent is to try to convince about achieving greatness (together! :) and also I agree with your point that we must declare that which the compiler can't infer and/or which we don't want to change when there is refactoring. My intent about brevity is avoiding declaring that which is arguably unnecessary, e.g.
Also the highly respected Paul Graham writes to design a programming language for the best programmers because they are the ones who be the most productive and determine the success of your language:
It is not my aim to remove the compiler's checking for correctness. Whereas, it is my aim to use clever to design of a programming language to make some checks irrelevant, e.g. afaics the need for P.S. anyone who figures out how I made the numbered list above display correctly in markdown starting from "2" instead of "1" is a hacker, hehe. |
@keean and @yoosiba I have made a strong logical argument that if TypeScript or N4JS can add |
@shelby3 I have decided to start a new project to develop a simple trait based, single-paradigm compile to JavaScript language for data-type driven generic programming as defined in "Elements of Programming" by Alexander Stepanov and Paul McJones . I would very much appreciate the input of anyone who is interested in trying to create something simple, type-safe and expressive, and I have created an initial issue to discuss the big-picture stuff here: keean/zenscript#1 |
@keen I know the difference between mine code and your proposal. It is just something I would do in N4JS if I would want to add new behaviour to the class without touching the class and without adding the superclass. N4JS doesn't have type classes. At least for now, in N4JS you can't modify type structure from the outside of that structure. We have static polyfils, but that is a bit different see 11.4.2 Static Polyfill Definitions in our spec (pdf) |
@shelby3 regarding PureScript:
These sort of statements clearly show that you haven't even tried to use the language. Please do that and find out in what way you are wrong. |
@yoosiba apparently Joose traits bind new behavior to the instance. Afaics, that is roughly the same as extension methods, which I explained are not the same as typeclasses. Typeclasses enable varying the behavior at the function invocation (application) use site. Object Algebras bind the data types to each operation, e.g. the construction of a literal data object is in the context of abstract class ExpAlg<E> {
E lit(int n);
E add(E lhs, E rhs);
}
abstract class IPrint {
String print();
}
class PrintExp implements ExpAlg<IPrint> {
@override
IPrint add(IPrint lhs, IPrint rhs) => new PrintAdd(lhs, rhs);
@override
IPrint lit(int n) => new PrintLit(n);
}
class PrintAdd implements IPrint {
IPrint lhs, rhs;
PrintAdd(this.lhs, this.rhs);
@override
String print() => lhs.print() + " + " + rhs.print();
}
class PrintLit implements IPrint {
int value;
PrintLit(this.value);
@override
String print() => value.toString();
}
makeExp(ExpAlg a) => a.add(a.lit(1), a.let(2));
print(makeExp(new PrintExp()));
print(makeExp(new EvalExp()));
abstract class MulAlg<X> extends ExpAlg<X> {
X mul(X lhs, X rhs);
}
class PrintMulExp extends PrintExp implements MulAlg<IPrint> {
@override
IPrint mul(IPrint lhs, IPrint rhs) => new PrintMul(lhs, rhs);
}
class PrintMul implements IPrint {
IPrint lhs, rhs;
PrintMul(this.lhs, this.rhs);
@override
String print() => lhs.print() + " * " + rhs.print();
}
makeMulExp(MulAlg a) => a.add(a.lit(1), a.mul(a.let(2), a.let(3)));
print(makeMulExp(new PrintMullExp())); Additionally without mixins providing multiple inheritance for Additionally Object Algebras appear to require the boilerplate of manually dispatching each operation to its nominal member, e.g. And this doesn't even touch on the concept of virtualized typeclasses, aka trait objects in Rust. Afaics, there isn't any substitute for typeclasses. We can't emulate them with subclassing and generics. |
It is amazing how much energy a young guy has to waste on unproductive ego battles. When I was his age, I was too busy coding and there wasn't any Internet to draw me away from production. @spion wrote:
Did you entirely miss the point of the comment post you are quoting from out-of-context? Or are you just trying to win some ego contest? (I presume both) The statement clearly shows that I am making a generalized statement about difference in grammar between mandated parenthetical grouping of arguments and otherwise. It is irrelevant to my generalized point, the left-to-right or right-to-left precedence choice for function application of the language which is the aforementioned "otherwise" case. And other factors such as the type signatures of But nice try any way. Keep digging for irrelevant details and finding the bark instead of the way through the forest. If you phrase your correspondence in an amicable and open-minded manner seeking production and constructiveness, then so will I. If you seek to destroy and belittle, then you will be looking in a mirror and eventually simply ignored. I received too much hate from several of you guys from the TypeScript community. Sorry if I don't agree with its unsound type system. Let the "language wars" begin, if that is your chosen mode of interaction.
Damn right I don't have time to try every language that is unsuitable for my needs. I never claimed I used PureScript. Heck I haven't even written any Haskell for some years now. I am trying to get something accomplished before hell freezes over. But if I write down precedence ordering that is different from a particular language or set of languages in my haste and sleeplessness, while also not diminishing the point I was making, then what utility does it serve to try to ridicule me with an irrelevant detail. You could simply point it out without trying to implying that I haven't done something that I should do (use the language). What gives you the omniscience to choose my priorities? I'll remember how to treat you when you have Multiple Sclerosis and struggle to have the energy to get all the various things done that you want to get done and used to be able to do before you got chronically ill. You inconsiderate fool. You have no fucking clue what I am dealing with on a daily basis. Try doing what I am doing with the brain fog I have. Imagine your head wants to be on the keyboard and you can barely hold your eyes open. I deal with this during most of my waking hours. I don't go around making excuses but it just shows how socially inept you are about things that other people may be going through in their life. It was so bad yesterday that I couldn't even make it through the video on Object Algebras. My eyes couldn't even focus on the code samples. Was a struggle to get through the video when I awoke. I might feel reasonably good for a couple of hours a day and other hours I am struggling to have any semblance of normal cognition and function. If you have no idea what Chronic Fatigue Syndrome is, what is does in reality, and the other symptoms of autoimmune disease, then you have no way to understand. Do you have any clue what the stress you dish out does to a person with MS? You are actually using a weapon which has physical ramifications. Warning: https://en.wikipedia.org/wiki/Cyberstalking#Distinguishing_cyberstalking_from_other_acts Apologies to N4JS for the choice of words. But some of these TypeScript packdogs (and it by no means appears to be representative of all TypeScript community members, although these few bad apples originate from there) just don't seem to get the clue, no matter how many times I have hinted to them to please stop the trolling. I told you several times that I am interested in your technical details. But you are always trying to find a way to ridicule me and fault me for not being an expert user of every possible language which I comment on. That is your agenda. It is not objectivity. It is a political agenda. Engineering is about stating facts, and there is no benefit to injecting ad hominem agendas. That crap destroys production. I suppose you are trying to get revenge for where I pointed out that you conflated subclassing and nominal typing, and yet you continued to deny it like a weasel. And do notice that I was considerate to you when I pointed out your error. You guys push me and push me until you can bait me into writing something like this. I try and try to ignore your continual trolling. I will need to find a place to have discussions about language design where people are considerate of each other. @spion I realize you are probably too young to understand wisdom, but again I will advise you to read and understand the following. It is written by a man with a 166 IQ who coined the term "open source":
When you are ready to mature and focus on interesting engineering discussions without the ad hominem noise, then I will be happy to enjoin you. |
I'm going to close this issue. That doesn't mean that I (or the N4JS team) will ignore the topics discussed here. I'm closing this issue for the following reasons:
|
@JensN4 regarding my reply to you and your follow-up reply at the Google group for Google's StrengthenJS initiative, I hence explained what I meant about the solution to eliminating covariance with type-classes. I'm not sure if I am correct, so if anyone can point out a flaw in that design reasoning, please do.
Edit: oh and back on the title of the Issue— the compelling market for N4JS. On further thought, the market is probably corporations who have some need to do soundly typed JS development, but don't want the lossy dissonance of Java →GWT →JS. Corporations are more likely to view subclassing and agile development principles within that prehistoric coding paradigm to be of great value. Whereas, the language @keean and I are potentially designing would be the cutting edge, but possibly even mainstreaming a unification and simplification of concepts from functional programming, Haskell, and making it closer to JavaScript. Let's see what comes. P.S. I am not trying to advertise in your project space, just my rebellious penchant for hyperbolic, colorful words and deprecating hacker humor (which seems to get me into trouble). |
@yoosiba and @JensN4 , you may find interesting or useful this summary of variance issues w.r.t. to subclassing, typeclass objects, and my new union solution to the Expression Problem. |
Thought of a potential hack to simulate typeclasses in N4JS. |
FYI, we already bumped into TypeScript's unsound "bivariance" (example in TypeScript's Playground provided). N4JS considered as an emit target. 😀 |
IDE-2453: IDE does not add .n4jsx files to the test-catalog
Per my reply to Jens von Pilgrim, I'm interested in (and I have a need for) a more soundly typed JavaScript variant than TypedScript.
However, I am questioning whether some of the design and target market decisions for N4JS can appeal to me or even to anyone who has a similar interest and need?
Meta: Please receive my criticisms as constructive, because I want to see what you all have to say and how it influences my logic on this issue. I am not writing this to criticize your admirable effort and technical excellence, but rather to determine how resolve the issues I have which are enumerated below. I am not trying to stomp on anyone's orderly orderliness here (not to insinuate that you all would be upset if I did), rather just being a voice from the outside to stimulate brainstorming about what is the use case and market for N4JS and whether some design decisions should change or not. Apologies given born and raised in the USA, although I have some German ancestry (Hartwick) I don't read or understand the German language, so all communication will need to be in English. Also note my avatar is a joke (myself at age 29), I am age 51 with 34+ years of programming experience. Apology if I start posting so forcefully without getting to know you all first, it is because I am very rushed and lacking time so please don't perceive me as an aggressive troublemaker.
I don't understand why I or anyone would to use N4JS instead of GWT (to compile Java) or Scala's Scala.JS compiler? Scala would give me the very desirable brevity of "everything is an expression" which JS doesn't have (yet).
But the reason I don't want to use Scala is because:
So why would I want to use a Java clone which:
public
by default which is the predominate case. In my experience, productivity doesn't derive from pedantic orderly orderliness tsuris, but rather from paradigms and big picture thinking. I don't want noisy code in the way of seeing the big picture algorithm.What I think I want is a soundly typed typeclass language where "everything is an expression" which otherwise has a syntax and semantics that is as close to ECMAScript as possible, so that the emitted JS code is comprehensible when debugging in the browser even without source mappings. I want it to be able to interopt with JS's structural typing as well, when I want to use that paradigm instead of typeclasses. And it must be a self-hosted compiler asap, and it should not have any dependencies which are not self-hosted.
I've searched for such a language and I can't find it. I've found Haskell clones such as PureScript but that deviates too far from JS semantics and forces a Haskell like purity and monadic effect system.
I think to create a significant enough niche for new programming language, you have to design something that people want which they can't find with a more established choice. Otherwise it is very difficult for you to attract a community of supporters (especially the early adopters) and the network effects that scale up an ecosystem.
What we really need is the simple language I have described above. I think such a language would be incredibly popular over time. And I would certainly become an enthusiastic contributor. Also I would work to popularize such a language by publishing and marketing popular ecosystems that featured this language. I've done million user software more than once in my career. (and I would help to select a more marketable/brandable name than "N4JS")
Thoughts?
The text was updated successfully, but these errors were encountered: