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: Re: Mixing operators and dot notation Date: Fri, 3 Jun 2016 22:41:11 +0200 Organization: A noiseless patient Spider Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Fri, 3 Jun 2016 20:41:12 -0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="6d84a6c85b8a1a019c7ed28ae8b7efda"; logging-data="30510"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/HRZZR+X3OW5dV46pAM5wl" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 In-Reply-To: Cancel-Lock: sha1:SuQevTWknuD8dl7chAsmPTaDTBQ= Xref: news.eternal-september.org comp.lang.ada:30592 Date: 2016-06-03T22:41:11+02:00 List-Id: Thank you for the detailed example. In fact I was doing something quite similar but temporarily went away of it because of the inability to use dot notation. I'm going to try again with operator "&". My solution used a base generic as formal for all subsequent formals, and it was the first time I saw the need for that, so it was quite engaging. Álex. On 03/06/16 19:31, Shark8 wrote: > On Friday, June 3, 2016 at 5:09:23 AM UTC-6, Alejandro R. Mosteo wrote: >> To give you the essence. I'm back to trying to get a minimal ReactiveX >> (http://reactivex.io)-like thing working. The gist is that you can chain >> many transformation operations: >> >> SourceType.Generate_Data >> .Op1 (...) >> ... >> .OpN (...) >> .Endpoint (Operate_With_Resulting_Transformed_Data); >> >> As long as the ops receive and emit the same type, I can do it with >> generics. But those are in the minority. Since they receive one type and >> emit another, I'm trying to find the most elegant Ada solution that >> keeps compile-time type checking if possible, and straight code flow >> (this is where parentheses in the solutions above don't work, since they >> create "boxes within boxes"). > > I'm doing something similar with Byron. > > Also note that the "boxes within boxes" can be used to some advantage as you can make generics dependent on generics: this requires some up-front designing and discipline though... and really learning the generic system. > > There is one possible solution for you that doesn't quite require such gymnastics: > > Package Testing_Package is > > Type Type_Interface is Interface; > Function Operation_1(Object : Type_Interface) return Type_Interface is abstract; > -- However many base operations there are. > > Generic > Type X is private; > with Function Op_1( Data : X ) return X; > -- with for appropriate operations. > Package Make_Interfaced is > > Type Y is new Type_Interface with record > Data : X; > end record; > > Function Create( Object : X ) return Y; > overriding Function Operation_1(Object : Y) return Y; > > Function "+" (Object : X) return Y renames Create; > Function "-" (Object : Y) return X; > Private > > Function Operation_1(Object : Y) return Y is > ( Data => Op_1(Object.Data) ); > > Function Create( Object : X ) return Y is > ( Data => Object ); > > Function "-" (Object : Y) return X is > ( Object.Data ); > > End Make_Interfaced; > > > Generic > Type A(<>) is new Type_Interface with private; > Type B(<>) is new Type_Interface with private; > With Function Operation( Item_1 : A; Item_2 : B ) return A; > Function Concat( Left : A; Right : B ) return Type_Interface'Class; > > Function Concat( Left : A; Right : B ) return Type_Interface'Class is > ( Type_Interface'Class(Operation(Left,Right)) ); > > > End Testing_Package; > >> >> I'm pursuing several approaches: one is to use a tagged type with all >> operations (which is the Java approach), and marshalling of arguments >> via generics (which java doesn't need by having in-place instatiations). >> That's not too bad but duplicates code, in the sense that for each >> operation you need too pieces: the operation and the marshalling, but at >> least the library user writes her code using only her own types, which I >> like: >> >> SourceType.Generate_Data >> .Op1 (FromXtoY.Transformer >> (User_FuncX'Access)) -- User_FuncX returns Y >> .Op2 (FromYtoZ.Transformer >> (User_FuncY'Access)) -- User FuncY returns Z >> .Endpoint (Z_Type.As_Z (Function'Access)); >> >> Of course with proper shorter names it looks better. However, checks are >> performed at run time. >> >> Another idea was to use "&" instead of dot notation, >> >> Stream := SourceType.Generate_Data & >> Type1.Op1(...) & >> Type2.Op2(...) & >> Type4.Endpoint (...); >> >> having all needed "&" in scope. This possibly requires more "use type" >> clauses and I haven't tested it yet but I think it should work and be >> neater, having a "&" taking different left and right types. >> >> Another way I was trying was the hybrid one that doesn't work: Using dot >> notation while there are no type changes, and & to cast to the new type >> only when needed. (I needed it to work even without parentheses.) >> >> The root of the problem is in that, to keep code natural (and >> compile-time checks) I want to keep the user unaware of class-wide >> wrappers, and that involves generics. Once you have generic instances, >> you lose dot notation for transforming operations (since you need to >> somehow glue two types together, and the new operations are no longer >> primitive). (On this path, I have an idea involving two instantiations >> for each type being used, but I'm trying to avoid that for now). (Also I >> had a neat approach using elaboration-time instantiations but I collided >> with accessibility checks since I didn't want everything to be at >> library level.) >> >> Anyway, I will keep playing and probably come back for criticism/ideas. >> It's possible I'm missing other options, of course, which are welcome. I >> will post my experimental repository once/if something takes shape. >> >> Álex. >