Enso - 2023-06-28 11:40:37

Summary: New page: [http://enso.org Enso] is a '''dual syntax''' programming language. '''Visual''' and '''textual'''. Unique. With the ability to use libraries from [[Java]], [[JavaScript]], [[R]] and [[Pyt...


[http://enso.org Enso] is a '''dual syntax''' programming language. '''Visual''' and '''textual'''. Unique. With the ability to use libraries from [[Java]], [[JavaScript]], [[R]] and [[Python]], without wrappers and with close-to-zero performance overhead.

[[I]] am responsible for its [[JIT]] compiler written on top of [[GraalVM]] since 2022.

MarketingVersion - 2023-06-06 04:53:16

Summary: /* Summary */


There is a difference between [[MarketingVersion]] and engineering approach to versioning, like [[Semantic versioning]]. Hear why:

===== Marketing Version =====

[[MarketingVersion]] is the one shown to end users and is associated with the whole product. It is a ''single label'' to help users understand and express what they are working with. Examples: ''Windows 10, Windows 11, Mac OS Sierra, Ubuntu 22.04, Ubuntu Jammy Jelly, Java 2, Java 11'', etc.

There is '''no logic''' in marketing versioning. It is purely driven by marketing and other '''human centric needs'''. Even using date based ''YYYY-MM-DD-dev'' versioning is [[good]] enough.

===== Engineering Version =====

Engineering versions serve other purpose: they ''allow code to verify'' if the [[version]]s of other components are good enough to work with. Usually a form of [[semantic versioning]] is used for that. Often the system uses [[RangeDependencies]] to express '''intervals of compatibility'''.

Engineering versions are '''associated with components''' - not the whole product. There is usually way more such component [[version]]s inside of a single (marketed) product.

The engineering [[version]]s shall be ''incremented according to rules of compatibility'' to signal [[compatible]] as well as [[incompatible]] changes. That implies:
* the engineering version '''must be different''' than the marketing version
* there are '''many different''' engineering versions across the product as each component evolves differently and needs different versioning

== Summary ==

There is a difference between [[MarketingVersion]] and '''engineering version'''. Keep that in mind and make sure you disassociate these two categories as soon as possible. The last thing a responsible [[API]] designer wants is to explain to marketing department what [[semantic versioning]] is - especially when trying to explain why changing the versioning from ''1.9'' to ''Jemmy Jelly'' or ''Java 9'' is a breaking change from the perspective of '''code''' and [[BackwardCompatibility]]!


[[Category:APIDesignPatterns:Evolution]] [[Category:APIDesignPatterns]]

Freedom - 2022-10-30 19:51:53

Summary:


Freedom for Everyone podcast: [[Image:Apitip07-FreedomForEveryone.mp3]] - too much freedom is going to hurt you! Just like [[wikipedia:mediawiki]] hurts me.

Portability - 2022-10-29 14:55:39

Summary:


When designing frameworks and libraries that shall be widely adopted it is important to increase [[portability]] as much as possible. If an [[API]] can be used on different systems, different configurations, the amount of users including such [[API]] in their applications grows.

The best way to hurt [[portability]] is to depend on a 3rd party [[API]] that isn't [[portability|portable]]. Depending on Win32 [[API]] is one such example as that prevents your library to run on [[Unix]]-like systems.

=== [[Portability]] of [[Java]] [[Libraries]] ===

Writing in [[Java]] (a [[language]] designed to ''write once and run everywhere'') greatly increases [[portability]].
However there is another axis hurting [[portability]] - the ''supported JDK'' version. Of course, should a library be widely used, it has to support as oldest JDK as possible. These days it is [[JDK]]8 - the primary reason being that [[Android]] supports [[JDK]]8 - as such, should a library aspire to be used on [[Android]] (as well as regular [[Java]]), it needs to stick to version eight. Btw. not that many years ago, [[Android]] only supported [[JDK]]6 and many libraries had to stay with [[JDK]]6 [[API]]s and [[language]].

Supporting the ancient [[JDK]] gives the application writers using such library or framework a [[freedom]] to choose their [[JDK]]. The application writers can then run on oldest or newest [[JDK]]. That's the kind of [[freedom]] they want.

=== Transitivity of non-[[Portability]] ===

There's ''transitivity of non-portability'' - the [[portability]] of the final application cannot be bigger than [[portability]] of the least portable library used. This applies also to 3rd party dependencies a framework or library has: again their non-portability may negatively affect portability of such framework or library.

Btw. [[NetBeans]] is facing this non-portability issues with [[Lucene]]. The [[Lucene]] team decided to stop supporting [[JDK]]8 in newest versions. That puts all [[Lucene]] users into a dilemma:
* drop support for [[JDK]]8 too
* stick with old versions
* backport new fixes/features into [[Lucene]] that still runs on [[JDK]]8

Btw. [[Spring]] framework is said to drop support for [[JDK]]8 as well. Why it works for them? Majority of the market. Nature of micro services?

[[TBD]]

Of course, writing portable libraries is harder. It requires more work from the [[API]] author, more self-control, more suffering. However such suffering is justifiable. There is usually a single [[API]] writer, but there are [[3SidesToEveryAPI#Mine|many users]] to it. What matters is to simplify and improve experience of those [[API]] users - own author suffering doesn't matter that much. On the other hand, there is no need to suffer needlessly. Even [[API]] writers shall have a decent life! What does that mean in [[Java]]? While an [[API]] writer wants to target the oldest [[JDK]] possible, there is no point in sticking with ancient [[Java]] syntax! Just use [[Frgaal]]!

What every non-masochist [[API]] writer wants is:
* high portability with respect to supported range of [[JDK]]s (maybe with help of [[AlternativeImplementation]]s)
* decent version of [[Java]] language
* code against selected old [[JDK]] [[API]]s, but use the latest [[Java]] features

This all can easily be achieved with [[Frgaal]].


[[Frgaal]] is the [[Java]] compiler for framework and library authors!

DeepHierarchy - 2022-09-24 05:18:35

Summary: /* Substitution Principle */


[[OOP]] encourages code reuse and may lead to deep subclassing hierarchies. Beware of that when designing [[API]].

=== [[OOP]] Models the World ===

Classic [[OOP|object-oriented programming languages]] are said to be inspired by nature and its
[[evolution]]. Everyone knows the example defining a '''Mammal''' class with basic methods describing
the behavior of every mammal, and various subclasses such as '''Dog''' or '''Cat''' overriding the methods
to do what cats and dogs do differently. This example not only demonstrates what
object-oriented languages do best, but it also ''justifies the whole purpose of [[OOP]]''. By showing how
easy it is to describe nature, the object-oriented concept is also elevated to be the right programming
technique to describe the real world. [[OOP]] languages are supposed to be more suitable
than traditional ones for coding and capturing real-world concepts.

=== Just an Intricate Switch ===

After maintaining a [[NetBeans|framework in Java]] for more than fifteen years, I don’t buy this. Honestly, ''virtual method dispatch''
is nothing else than an
''intricate switch statement''! A method call isn’t a direct invocation of some code but rather a
switch that chooses from multiple implementations. The switch is based on the list of subclasses
and can potentially grow as various developers create more and more subclasses. But
it’s still a '''switch'''. Of course, explaining [[OOP]] as an ''enhanced switch'' is
much less fancy than presenting it as a technology that helps us model the real world. That’s
why computer courses are likely to stick with the '''Mammal''' example.

=== Switch with no Limits! ===

However, I’ll use the switch
explanation to reveal an important hidden catch: when writing an [[API]], ''the size and behavior
of the switch is unknown'' to the writer of the code. This can be seen as an advantage, increasing
the number of ways that a piece of code can be reused. However, a few releases later, if you
don’t know the actual participants in the switch, you can have a nightmare on your hands.
Simply allowing an unknown party to participate in your code “switch” can be too open to be
maintainable.

=== Substitution Principle ===

When writing an [[API]], the term ''subclass'' shouldn’t be used for someone who can ''participate
in a switch'', but for someone who ''behaves exactly like me'', plus adds some additional behavior.
True, many would agree that a '''Human''' is a subclass (a specialization) of a '''Mammal'''.
Nice, but simply exposing a [[DeepHierarchy]] of classes is unlikely to improve an [[API]]’s usability magically.

Especially [[GUI]] toolkits (full of widgets inheriting from each other) got this all wrong.
They like to claim that a {{JDK|javax.swing|JFrame}} is a specialization of {{JDK|javax.swing|JComponent}},
but try to use {{JDK|javax.swing|JFrame}} where you can use {{JDK|javax.swing|JComponent}}! It is going to fail.
That is not a failure of the usage, but a failure of the [[API]] designer!

== Do Not Expose Deep Hierarchies! ==

Rather than exposing [[DeepHierarchy]] separate [[APIvsSPI]] and stay as flat as possible! If you have to expose subtyping, remember [[wikipedia:Liskov_substitution_principle|Liskov's substitution principle]]: if something is a subtype, it has to inherently
be ready to be used in place of the original super class or interface.

[[Category:APIDesignPatterns]]
[[Category:APIDesignPatterns:Anti]]

Frgaal - 2022-04-21 15:44:19

Summary:


I love [http://frgaal.org Frgaal] and you'll love it too: Wouldn't it be great to have '''record'''s and other latest [[Java]] language features available on your old [[JDK]]s? As old as [[JDK]]8? [[Frgaal]] allows you to do it. There is a [[Maven]] plugin, integration with [[Gradle]], a way to use it from command line... read more at http://frgaal.org


=== Can I use [[Frgaal]] via {{JDK|javax/tools|ToolProvider}} [[API]]? ===

Let's imagine we have a following code invoking the {{JDK|javax/tool|JavaCompiler}} via {{JDK|javax/tool|ToolProvider}} for a custom ''CODE'' snippet defining {{JDK|java/lang|Record}} with main method:

<source lang="java">
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;

class ModernJavaCompiler {
private static final String CODE = ""
+ "record R (String name) {\n"
+ " public static void main(String... args) {\n"
+ " System.out.println(new R(\"Hello World!\"));\n"
+ " }\n"
+ "}\n";

public static void main(String... args) throws Exception {
JavaCompiler compiler = javax.tools.ToolProvider.getSystemJavaCompiler();
List<String> arguments = new ArrayList<>(Arrays.asList(args));
arguments.add("-d");
arguments.add(".");
List<JavaFileObject> sources = Collections.singletonList(new Src(CODE));
JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, arguments, null, sources);
Boolean res = task.call();
if (!Boolean.TRUE.equals(res)) {
throw new IllegalStateException("Compilation failed: " + res);
} else {
System.out.println("Compiled OK");
}
}

static class Src extends SimpleJavaFileObject {
private final String code;

public Src(String code) throws URISyntaxException {
super(new URI("memory://Code.java"), Kind.SOURCE);
this.code = code;
}

@Override
public String getName() {
return "Code.java";
}


@Override
public CharSequence getCharContent(boolean bln) throws IOException {
return code;
}
}
}
</source>

This is a regular Java source file that can be compiled using standard [[Javac]] compiler:

<source lang="bash">
$ javac -source 8 -target 8 ModernJavaCompiler.java
</source>

The ''ModernJavaCompiler'' source code then uses {{JDK|javax/tool|JavaCompiler}} on its own to generate class ''R''.
It can be executed [[JDK]]-17 as

<source lang="bash">
$ /jdk-17/bin/java ModernJavaCompiler
Compiled OK
$ /jdk-17/bin/java R
R[name=Hello World!]
</source>

However executing the same steps with [[JDK]]-11 is going to fail as the [[Javac]] from [[JDK]]-11 doesn't support '''record''' keyword:

<source lang="bash">
$ /jdk11/bin/java ModernJavaCompiler
Code.java:1: error: class, interface, or enum expected
record R (String name) {
^
</source>

Can we fix that? Sure...

The idea would be to replace the standard "compiler tool" with the one coming from the [[frgaal]] project. Let's try to disable the regular compiler first. There is an option '''--limit-modules''' in [[JDK]]-11+ and the idea is to use it to disable standard [[JavaC]]:

<source lang="bash">
$ /jdk11/bin/java --limit-modules java.base ModernJavaCompiler
Exception in thread "main" java.lang.NoClassDefFoundError: javax/tools/ToolProvider
</source>

Great! Disabling works. The "compiler tool" is completely missing. Now there is a time to inject [[Frgaal]] instead. Following script shows how to get it all working:

<source lang="bash">
$ curl -o compiler.jar https://repo1.maven.org/maven2/org/frgaal/compiler/20.0.0/compiler-20.0.0.jar
$ /jdk-11/bin/java --limit-modules java.base,jdk.zipfs -cp compiler.jar:. ModernJavaCompiler
Compiled OK
$ /jdk-11/bin/java R
R[name=Hello World!]
</source>

Hey, using '''record''' on JDK-11!

Having '''record''' (and other [[JDK]]-20 language features) available on old JDKs is great, isn't it?


Embed [[Frgaal]] into your own programs and use the latest [[Java]] features on any [[JDK]]!

Rust - 2022-03-26 05:59:56

Summary:


[[wikipedia:Rust_(programming_language)|Rust]] is a modern successor of [[C]] - a low level ''system'' programming language without [[Garbage Collection]], but with memory safety! That safety comes from a strict ''linear'' type system - the strongest, but also hardest to use thing in [[Rust]]. [[I]] am just trying to rewrite my [[Sieve of Eratosthenes]] to [[Rust]] and it is almost impossible without reading [https://rust-unofficial.github.io/too-many-lists/ Too Many Lists] book. Will spending days of studying to implement something as trivial pay off?

=== JNI ====

It is surprisingly easy to connect [[Java]] with [[Rust]]. One doesn't have to write any [[C]] code. There is https://docs.rs/jni/latest/jni/ package.

Garbage Collection - 2022-03-26 05:43:44

Summary:


Every modern language has [[wikipedia:garbage collection (computer science)|garbage collection]]! In a [[language]] like [[C]] one had to manually deallocate all the allocated memory - without such clean up the running program would continually eat more and more memory. [[Garbage Collection]] offers a mechanism to do such cleanup automatically. It comes with some overhead, but at the end of last century [[Java]] demonstrated, it can be implemented quite effectively. Since then every modern language uses it - be it a dynamic language ([[Python]], [[JavaScript]], [[Ruby]], etc.), [[Java]]-like [[language]] like [[CSharp]] or even a compiled language like [[Go]]. There is just a single exception so far: [[Rust]].

GraalSpringTour - 2022-03-21 12:42:44

Summary:


[[Image:Labská.jpg|thumb|right]]
[[Image:Luční.jpg|thumb|right]]

== Canceling Luční bouda ==

I am at Labská bouda, but exhausted. Weather isn't great. I will not make it to Luční, sorry.

I got back home, but it was all a bit tough. First of all I had to start in 300m altitude lower than originally expected - not in [[wikipedia:cs:Horní_Mísečky|Horní Mísečky]], but in [[wikipedia:Špindlerův_Mlýn|Špindlerův Mlýn]] due to Saturday bus schedule. Climbing up was initially fine, but the closer to the top, the more windy and foggy it all got. In spite of that at 11:00 I had ski-skated up to [[wikipedia:Vrbatova_bouda|Vrbatova bouda]]. Honza Horváth (the only co-worker who RSVPed) called that the road from [[wikipedia:Rokytnice_nad_Jizerou|Rokytnice nad Jizerou]] was icy and he'd be delayed. Anyway at 11:30 I got to [https://www.labskabouda.cz/ Labská bouda] - however, to my horror, the cottage was closed. To fulfill my promise of ''happy hour'' (up till 12:30) I had to wait outside trying to contact Honza. When he finally picked the phone up (couldn't sooner as it was too windy to even pick a phone) he was in a shelter kilometer away from [https://www.labskabouda.cz/ Labská bouda] - I encouraged him to continue hoping he would show up in ten minutes. However he didn't and I was freezing for another half an hour. I gave up and went towards [[wikipedia:Martinova_bouda|Martinovka]] to rescue at least myself thinking about calling a rescue mission for Honza (not even picking a phone again). Finally Honza called - he had got lost and realized that only when crossing the Polish border. Honza sounded freezing and tired as well, so we called the meeting off and decided to return back where each of us started. I reached [[wikipedia:Martinova_bouda|Martinovka]], healed my freeze wounds and then quite tired continued down to [[wikipedia:Špindlerův_Mlýn|Špindlerův Mlýn]] bus station.

{{#ev:youtube|NUJCXi8y9No}}

If anyone was waiting for a ''happy hour'' at [https://www.lucnibouda.cz/en/ Luční bouda] then I deeply apologize! I was expecting nice spring weather when planning the [[GraalSpringTour]], but instead of that I got a typical ''Hanč & Vrbata'' storm. The prospect of leaving [[wikipedia:Martinova_bouda|Martinovka]] and going up to the roof of [[wikipedia:Giant_Mountains|Krkonoše]] again was killing me. I wouldn't make it to [https://www.lucnibouda.cz/en/ Luční bouda]. Let's plan something simpler next time!

== Celebrate ==

Let's celebrate [[GraalVM]]. The past, the spring, the future. Let's have a cross-country skiing tour. When? '''Saturday, April 2, 2022'''. Let's meet at two cottages in [[wikipedia:Giant_Mountains|Krkonoše]]:

* '''11.00''' - '''12.30''' [https://www.labskabouda.cz/ Labská bouda] - let's have a snack and a beer and then move on to
* '''16.30''' - '''18.30''' [https://www.lucnibouda.cz/en/ Luční bouda] - let's have a beer, dinner and either stay or move on

Getting there is up to everyone's own skills. People often travel to [[wikipedia:Harrachov|Harrachov]] and then walk/ski around Vosecká bouda to Labská bouda. Or they start in [[wikipedia:Rokytnice_nad_Jizerou|Rokytnice nad Jizerou]] and use the chair lift to get to Lysá hora. [[I]] plan to go from [[wikipedia:cs:Horní_Mísečky|Horní Mísečky]]. Remember, there is going to be some snow (view from [https://www.spindleruv-mlyn.com/cz/webkamera/34-webkamera-labska-bouda-okoli-spindlerova-mlyna-krkonose/ Labská], [https://kamery.humlnet.cz/cz/kamery/lucni-bouda/ Luční]). Hopefully the weather is going to be acceptable.

[[wikipedia:Špindlerův_Mlýn|Špindlerův Mlýn]] is a suitable starting point to get to both locations. Getting to Luční bouda is also possible from [[wikipedia:Pec_pod_Sněžkou|Pec pod Sněžkou]] - just walk the hill up or from Polish side - [[wikipedia:Karpacz|Karpacz]] - either walking (around [[wikipedia:Mały_Staw|Malý staw]]) or taking the chair lift to Kopa. Both locations offer accommodation. According to the best tourist maps [https://mapy.cz/s/kumevavesa it is three hour trip] from one location to the other.

To make [[GraalSpringTour]] more attractive [[I]] plan to buy beers and food for you, if you show up at the above mentioned happy hours and show an evidence of your positive attitude towards [[GraalVM]]!