Hacker News new | past | comments | ask | show | jobs | submit login

If the language allows you to simplify the program sufficiently it might be easier to just rewrite it from scratch when the requirements change. I doubt that this is the case for any language, but you know, in principle it could happen.



https://en.wikipedia.org/wiki/Write-only_language

>Languages that are often derided as write-only include APL, Dynamic debugging technique (DDT), Perl,[2] Forth, Text Editor and Corrector (TECO),[3] Mathematica, IGOR Pro and regular expression syntax used in various languages.


You've got me wondering about the utility of a genuinely write-only language.

As a thought experiment, would there be benefit to letting functions only be written once?

No-one could come along and break code by changing a function. If you wanted to fix a bug in a function you would have to write a new copy and explicitly update callers to use the new version.

A lot of maintenance overhead? Possibly, but tooling would take care of the majority of it. It would be useful to be explicitly know not just when a function has changed but when the functions it calls have changed.

You would need a naming convention, instead of Main you would need something like Main#23145. It would tick over very regularly.

Library functions like CalculateTax#12 would tick over less frequently.

By calling the old revision you could call the old code if you didn't want to update a module or function.

Perhaps you could extend that name to be something like Namespace.Name#IndirectRevision.DirectRevision.Hash which would allow tools to more quickly extract when the change was made in the logic of the function itself or when the change was in dependents.

This would be an alternative strategy to maintenance to IoC. Instead of treating dependents like they don't affect the code being executed, we can control instead the version of code

By forcing code change in all callers, you build up an explicit picture of where bugs happen but more important see also at the impact of those bugs on other places.

It would need great tooling to get over the paradigm shift of moving away from IoC but I think it would be interesting.


This is exactly the main idea behind the Unison language.[1] All functions are immutable and identified by a hash rather than name. When you make any change you are creating a new function with a new hash. It's definitely a very interesting idea.

[1] https://www.unisonweb.org/


What an absolutely fascinating idea! As the field of software engineering matures, how million line repos get maintained is going to become a subject of academic study.

> If you wanted to fix a bug in a function you would have to write a new copy and explicitly update callers to use the new version.

Finding all callers is the hard part though! And in modern languages, that need to be addressed both at compile (or "compile") and run time.

Assuming you've got all the call sites with what constraints you were given and have imposed, the second part, where you call a specific version of a function, is where it gets tricky.

Is the bug in the calling code or the called code? because huge software maintenance is obtuse. The original programmers have all long since left, so what we're left with is a smattering of random specific version calls, with only the tiniest of tidbits of history, locked away in someone's email, and saved in the previous ticketing system.

So it sounds interesting, but I worry (though I worry about a great many things), that the programmer three years later, ends up coming across calls to three different versions of some code, with no guidance on which ones can be upgraded, should be upgraded, and must not be upgraded. I can't say which one would involve digging up more ancient history though.


> Finding all callers is the hard part though!

Only because we made it hard by storing code in files instead of a database.


> explicitly update callers to use the new version

In a genuinely write-only language, how do you update those callers? You can't, you'd have to write new ones to call your new bugfixed function. And then you'd have to write new callers of those callers...

You'd have to rewrite the whole program every time you wanted to make a change. Which would make bug-fixing a much more cerebral activity since you'd want to work out as many as possible before the rewrite to save time.


The idea is interesting. However, worth noting that you would have to increment main() with literally every change, because when you fix a bug in foo#10 (by rewriting as foo#11), you'll need to update the affected call sites to use foo#11 instead, which means they get incremented, too, so you need to do the same to their callers, all the way up to main.

You'd absolutely need tooling to automate some of this (present a list of call sites; you select which should use the new function). It would also increase the size of your code base by a lot, although I'm not sure that's as much of a problem since we may be spending less time reading code and more just writing a new function.



You'd essentially be semvering little bits of your code.



I'm curious if this is used for anything…it sounds very blockchain-ish.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: