From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: "Alejandro R. Mosteo" Newsgroups: comp.lang.ada Subject: Musings on RxAda Date: Wed, 14 Oct 2015 16:30:08 +0200 Organization: A noiseless patient Spider Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7Bit Injection-Date: Wed, 14 Oct 2015 14:28:04 +0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="826cc6ce18acb660eb2ad190ef62dc45"; logging-data="4403"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+bnopH3rw6hEjikqft8bCa" User-Agent: KNode/4.14.1 Cancel-Lock: sha1:667ZsqHtgGMQ4CzzSK5mMdIqoOI= Xref: news.eternal-september.org comp.lang.ada:27973 Date: 2015-10-14T16:30:08+02:00 List-Id: Hello all, having been recently working on Java/Android apps, I have been exposed to the ReactiveX framework [1]. I think it originated on C# though. [1] http://reactivex.io/ Anyway, the gist of it is that you chain function calls (operators in their jargon) to process data asynchronously. This, in Java, with lambda functions and parameter inference leads to extremely compact, legible code that may notably simplify multithreading code. But I'm not here to advocate RxJava. For now I see it as an interesting challenge from an implementor point of view. When using it I started to think how this could be implemented in Ada. My ideas are not very elegant. I'd like to know your opinion/ideas on if this is doable in Ada (which could lead to a potential RxAda library ;-)). For simplicity, I'm going to concentrate on the "map" operator, as seen on this Java example: Observable.just("Hello, world!") .map(s -> s + " -Dan") .map(s -> s.hashCode()) .map(i -> Integer.toString(i)) .subscribe(s -> System.out.println(s)); Basically, the map operation takes some input, changes it somehow and outputs another type. The chain begins at an Observable (some data generator) and ends at a subscriber (which does something with the result). The above example takes a string, appends a signature, hashes it, and outputs the hash as a string. This does not necessarily has to happen at the moment of declaration; in general, observables emit data asynchronously. Moving into Ada, we need an Observable type able to take different map implementations. That could be (not compiled, bear with my mistakes. Allow for 2012 syntax): type Observable is [limited?] tagged record; type Datum is abstract interface; -- or maybe tagged null record; function Map (This : in out Observable; Map : access function (X : Datum'Class) return Datum'Class) return Observable; -- or access Observable if limited Here the 'Class are needed to avoid multiple dispatch, I think. Then you'll have to declare beforehand any mappings you need (which is more verbose and, lacking lambdas, would somehow defeat the purpose of having the logic in the chain declaration, but I see no way around it, unless the new simple expression functions can appear in-place?). Also, the need for 'Class parameters will force explicit casts in the user mappings, which I find ugly and leaves the type checks to runtime. I guess an implementation of "RxAda" could provide many Map profile overloads for basic Ada types (from String to String and so on), but still that's a poor's man attempt. That's as far as I've got, which is not much, but I'm a bit rusty on Ada right now. I can think of even more contrived ways using tagged types plus generics but I'm not sure they lead anywhere. I think it boils down to Ada not having lambda functions nor implicit template types a-la C++. Your thoughts welcome! [1] http://reactivex.io/