GitHub - pen-lang/pen: The programming language for scalable development

40 comments · 75% upvoted · source · other discussions

comments

TheUnlocked

I'm not sure I agree with not having generics increasing maintainability. The whole purpose of generics is to make code more maintainable by having single functions that support many types, rather than needing to maintain a separate function for each type. There's no reason that I should need to have five different linked list implementations for my five different types of record that I want to use linked lists with.

Strum355

Youd think given that this language is heavily inspired by Go that itd have learned from the decade of Go not having generics and all the interface{} baggage and maintenance issues that brought along with it..

bullno1

No generic just means doing it poorly with runtime cast or external templating tools, depending on what the language allows. You could still totally have one linked list but it's unsafe.

Even a Java-style type-erasure would greatly improve safety. All it does is checking at compile time and use Object at runtime.

78yoni78

yeah it sounds to me like saying no functions increases maintainability

[deleted]

Do they truly and reliably live up to that purpose, though? More specifically, do we have any quantitative evidence for the maintainability claims often stated for generics? If you want predictable performance characteristics, and especially if you want optimal performance characteristics, aren’t you going to end up writing five different linked lists anyway, even if it’s the compiler generating the monomorphic version and doing the work of optimizing each? Of course that’s a bit of a red herring, since if you wanted the performance characteristics you wouldn’t be writing linked lists in the first place, but you can see the point.

I get why there’s a social pressure to include generics, and why languages that omit them end up trying to retrofit them to assuage that market demand (see Go), all based on what feels like reduced code repetition, but I’ve always felt like there’s a price to be paid for every abstraction and — just as what happened with multiple inheritance in OOP — and I’m not sure we’ve yet bothered to actually quantify either the cost or the benefit of adopting generic functions before unleashing them as the de rigueur language feature du jour.

I’m interested in seeing how languages without generics solve their problems in practice, and how they perform In terms of maintenance metrics when compared to languages with them, especially at scale, but it was kind of tragic to see so many who didn’t actually use Go at all refusing to do so (and worse, counseling others not to) all because of a lack of something that might not actually be much more than a pervasive and persistent cognitive bias.

ipe369

aren’t you going to end up writing five different linked lists anyway

No, because i'm not microoptimizing each data structure for every different usage, AND because optimal data structures will still have very similar access patterns regardless of the type they contain

std::vector<float>, std::vector<int>, and std::vector<my_big_struct> all have exactly the same performance characteristics, there's no need to rewrite std::vector for any one of these types

do we have any quantitative evidence for the maintainability claims often stated for generics

I don't believe quantitative evidence is useful for programming, you can't get a controlled environment & you can't get a big enough sample size, & beyond that there are too many variables that are heavily dependent on one another

[deleted]

Even if you’re not micro-optimizing — which belies the assumption that you care about performance characteristics — then the compiler is, unless each of those data structures compiles to precisely the same instructions on each architecture — and I dare say neither of us has checked across even just primitive types — the binary ultimately has no generic implementation within it.

And the “I don’t believe that quantitative evidence” line is precisely why Computer Science is misnamed… plenty of vastly more complicated systems have prove amenable to quantitative analysis and you absolutely can get the controlled environment and the sample size. Moreover the threshold beyond which you can no longer analyze something quantitatively is itself a quantifiable which will need to be established before the “I [do or do not] believe” claims will hold real weight.

Without even attempting to quantify the properties of generics and validate or invalidate the claims made about them the arguments both for and against them are effectively religious ones, and while that sort of faith might be sufficient for our individual filters, it’s not really something that should be sufficient to carry the weight of the market either towards or away from a novel language design.

Moreover “languages with generics are more maintainable” is inherently a claim of quantification… there’s a dollar value that can be assigned to maintenance velocity and if that claim has any factual basis whatsoever then two curves can be drawn to support it. If the claim is that the vector acceleration of generics is so sufficiently large that it should determine the languages on the market then it’s certainly worth the effort to quantify.

ipe369

Even if you’re not micro-optimizing — which belays the assumption that you care about performance characteristics

I don't understand the word 'belays' here - do you mean that not micro-optimizing means you don't care about performance characteristics? because i would strongly disagree

the binary ultimately has no generic implementation within it

Correct, but this changes nothing, you can get the same performance characteristics from a data structure like std::vector regardless of codegen - codegen isn't really that important compared to data layout / accesses

it's worth noting that go DOES have a generic list structure, it's just builtin to the lang

Moreover “languages with generics are more maintainable” is inherently a claim of quantification

Good thing i never claimed that, and never would!

[deleted]

I don't understand the word 'belays' here - do you mean that not micro-optimizing means you don't care about performance characteristics? because i would strongly disagree

Sorry, that was an IOS autocorrection of “belies”, but yes, if you’re not micro-optimizing (eventually) then your highest priorities just aren’t performance characteristics. My point is that, quite often, performance characteristics are the highest priority, and when they are generics end up being manually unwound and replaced with monomorphic implementations.

Correct, but this changes nothing, you can get the same performance characteristics from a data structure like std::vector regardless of codegen - codegen isn't really that important compared to data layout / accesses

The relative impact of each is going to depend entirely on the compiler internals of the given language and just how much low level control is afforded for manual intervention in data layout, etc., but, sure, a generic vector<T> will have the same index access performance as any other, but sum(vector<T>) will have a different most efficient implementation for any given T, for instance if multiple T can or cannot be packed into a single register for SIMD.

it's worth noting that go DOES have a generic list structure, it's just builtin to the lang

Sure, and that’s quite possibly all the polymorphism actually required in practice.

Good thing i never claimed that, and never would!

Good. Though without the claim that they make code more maintainable it’s unclear why anyone complains about their inclusion or exclusion from a language.

ipe369

then your highest priorities just aren’t performance characteristics

I strongly disagree, you don't need to care about performance for all things - and you already don't! Go's hashmaps / vectors are already generic! Nobody is hand-optimizing a map implementation for every single type they need, are they?

Sidenote: If Go really was striving for known performance characteristics, then it wouldn't have a GC

sum(vector<T>) will have a different most efficient implementation for any given T

I'm not claiming that ALL generic implementations will have the exact performance characteristics across ALL instantiations, i'm just claiming that many generic implementations will have the same performance characteristics across many instantiations

Sure, and that’s quite possibly all the polymorphism actually required in practice

Maybe list & map sure, but also having generic iterators is useful for writing fast code that avoids copies (see rust's iterators, probably the best iterator system in any lang i've seen to date)

Though without the claim that they make code more maintainable it’s unclear why anyone complains about their inclusion or exclusion from a language.

You can still make persuasive claims without empirical studies just by reasoning through how different language features interact, assuming everyone involved has done programming in the language you're talking about, and they're on the same page about some basic axioms

For Go's case, it's very obvious just looking at any code that the lack of generics just forces many things into an interface{}.

I would never make the claim that generics makes things better universally, which is why i have such a problem with empirical studies - becaues this claim will never be true! For an empirical study to come to a reasonable conclusion that doesn't lost any nuance, you have to narrow down the criteria to such an extent that your sample size becomes too small

Why empirical studies aren't useful

This ended up in an essay, i feel like it's important for me to explain at this point. Here's how you would do an empirical study that properly limited variables for generics, you can probably start to see why it's be pointless:

You would need to create 2 identical implementations of go, then fit generics onto one of the implementations, then have multiple large software projects built with each of the implementations (with the same development methodologies, similar tools, similar developer 'skills'(however you measure that) etc, similar domain (e.g. web)).

After that you could MAYBE make a strong empirical claim about generics, but that claim would be so conditional that it wouldn't be very valuable (what if your developers were much more skilled? what if you did game dev instead of web dev?), and the costs of doing this study would be astronomical

AND you have to come up with a way of quantifying 'developer skill', which is a whole ordeal in itself

editor_of_the_beast

Downvoted exclusively because we absolutely should try and empirically learn more about software. There are challenges with it, but you can’t outright dismiss it as useful.

ipe369

the problem is that every empirical study gets to swan around like it's universally true, when the methodology is always flawed because they're missing out loads of variables

instead all empirical studies just get used to bash programmers over the head with more ridiculous dogma like 'we should reduce code duplication because that has been shown to make code simpler', except it doesn't make code simpler in MANY cases... your study just glossed over all the nuance because it tried to reduce a system which fundamentally couldn't be reduced

maybe empirical data could theoretically be useful, but it hasn't yet been shown to be empirically useful;)

Dykam

Vote. If you think something contributes to conversation, upvote it. If you think it does not contribute to the subreddit it is posted in or is off-topic in a particular community, downvote it. https://reddit.zendesk.com/hc/en-us/articles/205926439-Reddiquette

Even though you disagree, it's still a contribution.

Edited for clarity

[deleted]

Man, am I wishing more people on this thread had read that… apparently I didn’t contribute to this conversation at all.

HortenseAndI

I think we all know that upvote/downvote on opinion comments are generally treated as agree/disagree. This is kinda necessary because there's no secondary method to indicate disagreement with a comment (other than making another comment) which nonetheless obviously promoted discussion. And I think that's fair because otherwise how are you gonna know what way public sentiment (amongst the small number of people who read the comment) leans?

editor_of_the_beast

Don’t you mean the opposite, that it does contribute even though I don’t agree? What are you trying to say?

Dykam

I think I had the double negative right, but I just rephrased it as it was kinda hard to parse.

(Just for reference, I'm not downvoting here, that's someone else)

bullno1

I’m interested in seeing how languages without generics solve their problems in practice

Developers are already writing generic code poorly without the help of the compiler. Depending on libraries or teams, go has all of the above.

[deleted]

I’m interested in seeing how languages without generics solve their problems in practice,

I've been using a private systems language for decades, and for what was a fair range of systems and applications programming.

The lack of generics has NEVER been an issue.

The few times I might possibly have benefited (eg. from using the same routine for counting items in a linked list instead of needing 2 or 3), have been more than offset by not having had to design, implement, document and maintain such a complex feature.

It's also possible that a few things that people use generics for, I already make available.

If you take an abs() function for example, it will need to apply to a handful of integer or float types. How should a language that? It could use a generic function; or function overloading, or function-like macros; all heavy-duty additions to a language, and all needing additions to systems library, or some sort or prelude.

I just make abs() an operator, just like 'negate', which have built-in overloads.

[deleted]

Thanks for this. Considering I seem to have gotten several downvotes just for pointing out that we don’t actually seem to have much more than anecdotal evidence for the promise of generics it’s good to see at least one anecdote from the other direction.

moon-chilled

Even smaller than Go!

Wow, Go! is a rare inspiration for programming languages these days.

[deleted]

I've been trying to take a look at this language for ages, I can't get past Google's ignorance of '!', thank you.

[deleted]

I am using Go in a production server without searching Golang tutorial. It's that simple of a language

I saw some Go-gin and Gorm documentation/guides and started using it. Now I can say I am real good with it

pm-me-manifestos

I'm confused - you're proposing a statically typed purely functional language without genetics? How will you implement monads to perform IO?

[deleted]

Jeez, just copy-paste the function and replace types! /s

nekokattt

So templates?

/s

faiface

I mean, you don't necessarily need monads to do IO, you can also use algebraic side effects, or you can use continuations (just like .then(...) in JS). In any case, you're still gonna have a lot of trouble without generics.

Innf107

And how are you going to type your algebraic effects without generics? :)

editor_of_the_beast

What features help achieve the goal of ‘scalable development’? It doesn’t look radically different than any other language out there.

InsanityBlossom

Is there any example program written in it, to see what it looks like? The documentation only covers the syntax.

[deleted]

[removed]

HortenseAndI

I personally love the claim that few if any other languages have been designed with the developer experience in complex systems in mind. It really gives you a sense of who the creators are

[deleted]

[removed]

HortenseAndI

The actual quote is 'although many programming languages have been solving problems of programming in history, few of them actually tackled ones of software engineering, where you also need to maintain and keep making changes to existing software continuously', from the Github docs in the original post link. Anyway I mention this only because Scala is far from the only other languages which has similar goals in mind, but there's a certain... I wanna say 'smug disregard for everything else' in the tone of the copy for pen, but maybe I'm being unfair. Perhaps a Sunday evening is not the best time for me to consider this

[deleted]

This new language is apparently so small, simple and portable that you can use it anywhere.

Presumably that's why you can only get it for Linux! (Windows requires a recent W10 + WSL.)

Also, after extolling the virtues of Go's simplicity, it seems to be implemented in Rust (the few source files I could see were in Rust; no idea if that is the main source code).

So how big is it exactly; has anyone installed it? Just to see if the result of vastly simplifying the syntax and type system, and throwing out pesky features like mutability, pointers, and global variables, does actually result in a small implementation.

roosterHughes

the virtues of Go's simplicity

"Go!" not "Go". I made the same mistake. Link open from u/moon-chilled's comment further up: https://en.wikipedia.org/wiki/Go!_(programming_language))

I think this is spot on as a goal, and I love the ethos. Gag at pushing generics off, but I'll take the rest.

[deleted]

You’re kind of straw manning empirical studies there — sadly, not an unusual tactic amongst both Software Engineers and Computer Scientists — as you don’t actually need to reach the point of a fully double-blind, all variables accounted for comparison to make meaningful inferences, even if such a study might, eventually, be required to confirm those inferences, were the signal strong enough.

The claim I’ve been discussing is that generics make code more maintainable than code without generics… well tracking maintenance investment is quite simple, that’s just time tracking, and one need not have particularly large systems, just the same problem tackled via a generic implementation and one forgoing generics, then introduce extra test cases over time that trigger maintenance effort. You can then gather qualitative data (Likert scale, how effort was involved in maintenance rounds?, that sort of thing) and quantitative data (time spent navigating the file, lines changed per feature, and so on) and compare. Do this numerous times over numerous problems and we build up ability to distinguish signal from noise.

My guess is what you don’t get is a null effect, which is itself a step in the right direction. If generics have a strong positive effect then great, we’ve got at least a minimal reason to believe that folk wisdom might have value here (which is more than we’ve got now), while strong negative would validate further exploration of languages that lack generics. If there’s a weak positive or negative effect then at least we have eliminated the null hypothesis. We’re not looking for six sigma threshold of discovery, we’re just looking for some reason to suggest that such economic claims about language features — which is ultimately what “more maintainable” is — are more than untested and unmotivated opinions. A series of cheap studies with progressively more rigor would, at the very least, give us some idea that such opinions aren’t entirely hot air.

complyue

I'm interested in the "System Injection" part, how is it similar to handlers of algebraic effects? Didn't find an example of it.

No "circular references"? I wouldn't consider it "production ready" without this, if you mean a general purpose programming language.

Just personal thoughts but I don't think a single PL can scale across all domains consisting a computer based business supporting system. Each domain would better have its own DSL, free of concerns (implementation details and even conception details) in other domains. The computer working is just one domain among them, every jargon (keywords of one DSL e.g.) should be considered pollution to the conception space of other domains if put there.