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=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,21960280f1d61e84 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Newsgroups: comp.lang.ada Subject: Re: How come Ada isn't more popular? References: <1169531612.200010.153120@38g2000cwa.googlegroups.com> <1mahvxskejxe1$.tx7bjdqyo2oj$.dlg@40tude.net> <2tfy9vgph3.fsf@hod.lan.m-e-leypold.de> <1g7m33bys8v4p.6p9cpsh3k031$.dlg@40tude.net> <14hm72xd3b0bq$.axktv523vay8$.dlg@40tude.net> <4zwt33xm4b.fsf@hod.lan.m-e-leypold.de> <1j7neot6h1udi$.14vp2aos6z9l8.dlg@40tude.net> <1170347180.14376.104.camel@localhost.localdomain> From: Markus E Leypold Organization: N/A Date: Thu, 01 Feb 2007 18:36:29 +0100 Message-ID: User-Agent: Some cool user agent (SCUG) Cancel-Lock: sha1:hg3XodmG9KI0o212MD48QjOJEDc= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: 88.72.246.10 X-Trace: news.arcor-ip.de 1170351095 88.72.246.10 (1 Feb 2007 18:31:35 +0200) X-Complaints-To: abuse@arcor-ip.de Path: g2news2.google.com!news3.google.com!news2.volia.net!newsfeed01.sul.t-online.de!t-online.de!newsfeed.arcor-ip.de!news.arcor-ip.de!not-for-mail Xref: g2news2.google.com comp.lang.ada:8821 Date: 2007-02-01T18:36:29+01:00 List-Id: Georg Bauhaus writes: > On Thu, 2007-02-01 at 15:22 +0100, Dmitry A. Kazakov wrote: >> On Wed, 31 Jan 2007 16:16:20 +0100, Markus E Leypold wrote: > >> > I notice, that nobody that actually has tried >> > FP doubts the superiority of the style in general (they are bitching >> > about efficiency, sometimes, and availability of libraries, mor >> > often). > > FP is superior to what? Superior to not having "full" closures. WRT to abstracting over parts of an algorithm / solution / component. The full context of this comment of mine was: > > >> If yout have only downward scopes for "closures" and memory allocation > > >> this will, finally, interact badly with the fact that "implicit > > >> (i.e. static type safe) casting" of classes is also only possible > > >> downwards. My impression is, that all these things together rule out > > >> some useful designs, that would otherwise possible. Or to say it > > >> differenty: Object orientation w/o indeterminable scopes, upward > > >> closures and GC doesn't work well. Some abstractions cannot be > > >> implemented. > > > Umm, I cannot tell. > > I think I can tell, but the discussion on this topic (what is > > functional programming good for) does still rage on c.l.f and the > > relevant mailing lists. I notice, that nobody that actually has tried > > FP doubts the superiority of the style in general (they are bitching > > about efficiency, sometimes, and availability of libraries, mor > > often). > I'm saying this having had some fun writing > small OCaml command line tools. There are many good > libraries. And some things are just easy to write. > > Hm. The compiler error message are as helpful as you > would expect from inference machines (on a par with Hugs or C++ > template error messages). GHC has been improved in this regard. > > But how would you know that those who have tried FP don't doubt the > superiority of the style? Admittedly, I don't. It's only difficult to dicuss the question wether one would want to have e.g. closures, with people who haven't tried it. As I wrote elsewhere: All common programming languages are Turing complet, so equivalent. There is nothing that can be done in one that could not be done in the other -- in principle. So there is nothing like a proof "you cannot do X in language L" or "without feature F". There is just how "easy" it is to express things and this is, to an extend highly subjective. > Any statistics? What does "in general" mean here? My private head count. OK. I haven't proved it. > Are they really thinking that the inferior crowd doesn't write > recursive functions? > Well, perhaps that is true... Well, see, .. > GCC does try to > eliminate tail calls, though, so maybe we can see a shift from > loops and counter manipulation towards recursive subprograms some day. > ;-) ... as you see yourself, the language has to provide some support to make that efficient as a general technique. > One of the great new pieces of Ada 2007 is Ada.Containers in my view > precisely because it permits what is taken for granted with FP or > with scripting languages: lists, tables, and sets, and ways to Yes, but in an imperative way. Still, it's progress, I completely agree. > use or write generic algorithms involving all of them. > There isn't a lot of curry in there, but much else. Currying is somewhat overrated, but's it's hardly the essence of FP. > To me, many of the FP advocates seem to be mathematicians. If you I studied physics when I were young ... > look closely, two phenomena appear frequently in e.g. OCaml programs: > > (1) Either they use functions assembly language(!!!), What do you mean by that? > (2) or they use reference types and assignments almost exclusively. Don't know who "they" is here. Certainly not me nor Richard Bird nor the Haskell crowd in general. Yes, Ocaml, because of it's imperative elements has some potential to get abused. Writing reusable components though, is, IMHO, done by embracing a functional style. > -> (1) can be attributed to the programmer being a mathematician: > function assembly is a game in logic. Might be fun. Is it easy? It's rumored to be accessible to certain optimization techniques. I assume you mean the so called "point free style"? > What about review, changes, maintenance? Since point free style works well together with equational reasoning: A big yes on all counts :-). Side effect free FP also makes it possible to keep the old version for reference and for testing slave the old and the new version together. let foo_old x y z = ... ;; let foo_opt x y z = ... ;; (* new foo function, optimized *) let foo x y z = let old = (foo x y z) and opt = (foo_opt x y z) in if not (old == opt) then raise (Testing_error "foo_opt"); opt This technique is too expensive and cumbersome in imperative programming (yes, I tried it, it sucks, even for simple stuff). > -> (2) is a strange thing: These are imperative programs, written > in some allegedly functional language, and they are written this way > because they will then run faster most of the time. No. they don't as a general rule, but don't tell them :-). > What would Peter Naur have to say about this von Neumann style? > > Among FP advocates, there is always someone who just forces computers > to be abstracted into a function instead of considering what a > programmer MUST do and what most actual programming is all about: > manipulating the machine in operation, not manipulating some model of > functions. Programming, IMO, is not, manipulating the machine, but processing data. > > So why doesn't someone tell the FP people to advocate a theory of > functions that > > (a) match empirical comput*ers* better than they match some model > of comput*ation*. What's your problem with that? I actually don't even see the problem you're trying to address. Care to elaborate? And shall we shift that thread to c.l.f :-)). It's a bit quiet there at the moment. > (b) are no harder to analyze WRT O(?) than plain old procedures? They aren't. > Wait, Haskell is trying (a) by capturing imperative statements > in monads. The chapter on fusions in Bird's Haskell book lets me > think that you add simplicity by mixing FP with imperative style > when memory or speed are a consideration. No, you don't add simplicity. Monad style by sequencing state through the "operations" is just a ticket to grant the underlying compilation system the opportunity to do more optimization. Monads, IMO, are not imperative. They are a cute trick to enforce data flow by the type system in such a way that state (the state of the world in case of the IO monad) can be updated destructively by the VM or run time system instead of having to retain the old value on the heap. Which would be a bit difficult in case of the world state, anyway. >> > BTW -- another argument _for_ a builtin list syntax. >> >> Hey, Ada already has ()-brackets. Maybe our Unicode fans would propose >> special glyphs for )), ))), )))), ))))), )))))) etc. Is it what you mean as >> special syntax? (:-)) No. > > Actually, a syntax that is used in a theory book is > {left/right paren}{subscript i}. > The different lists of statements of an Ada program are marked using > more or less different pairs of brackets (if .. end if, loop .. end > loop, do .. end, ...). > > What does a list syntax buy us if there is no argument pattern matching, > or no data structure pattern matching in Ada? Brevity? Nothing. If you don't have the infrastructure to deal with lists in a flexible way (functional lists, not containers) it doesn't buy you much. >> > One point is, that >> > the type fitting into a slot in a functor or as a parameter of a >> > procedure might well never have been defined explicitly but is a >> > result of type inference. >> >> Why bother with types if you can infer them? I suppose, because you only >> think you can... (I don't know what that is supposed to mean: The OCaml people must be dreaming.) > It is considered good Haskell style to list the function > type before the function. I like it being able to write OCaml code > that does the same, > > let inc: int -> (int -> int) = > fun k x -> > x + k (* (+) forces int anyway *) Yes, but you certainly do not declare all types of intermediate results. Annotating function types is a good style, but again not for short functions like let dup = List.map (f x -> (x,x)) > > Actually, to be more general and stylish, I could have written > > # let inc binop increment arg = binop increment arg;; > val inc : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c = > > Hm. I wanted binop taking two 'as - the implementation might > change and require that binop be symmetric. I've problems with that "require". :-). If you use 'inc' in a module interface you'll have to state it's type (will not be interfered. So you have to decide early on in this case. In the other case it's not part of the module interface, so not part of reusable component. So nobody cares if it changes. "People" will not use it., > When people have used my inc with a binop taking different types, > they will have to change their programs too. Ouch. > So maybe I can think of some trick to make the inference > circuits assume binop takes two arguments of type 'a. > Or just write what I want and name the types! > How is this FP style superior, besides being brief and full of > assumptions? Have your way: It's not. I don't want to make unwilling converts to FP. FP and more to the point the Hindley-Milner type systems were only a point to illustrate some things in my discussion with Dimitry where he said, that things cannot be done differently than (...) etc. They can, SML/OCaml/Haskell are the living proof. If anybody decides he/she doesn't want it -- be free to ignore FP. But we started out (somewhere in the middle) with the statement of Dmitry that one "wouldn't want closures" (I'm quoting from memory) and that as a general statement doesn't hold water. Therefore and to illustrate what you can do with closures and a different type system my continued references to OCaml. If it didn't convince you -- probably my fault. Nonetheless I refuse to discuss merits of languages ot a micro level like: > So maybe I can think of some trick to make the inference > circuits assume binop takes two arguments of type 'a. > Or just write what I want and name the types! > How is this FP style superior, besides being brief and full of > assumptions? That is not FP. That is, essentially, your style when interacting with OCaml and your problem. > Sure the function is a value that can be passed around freely, > and can be used in currying. OK. This is another technical > facility that is powerful. Yes, passing functions around is powerful. Having a 'a type is also powerful. That's basically all I have been asserting. It helps a tiny bit not to have to declare the types of lists (a parameterized type) all the time like in let l1 = List.rev (...) in ... or let l2 = 5 :: l1 in ... which make the use of parameterized types much less clumsy than if you had to. So type inference is useful too, but of course good annotations are good style. You're not forbidden to annotate, where you think it helps understandability. > > generic > type T is private; > with function "+"(a, b: T) return T; > increment: T; > function Inc(arg: T) return T; > > function Inc(arg: T) return T is > begin > return increment + arg; > end Inc; > > Looks like more code, and I hear an FP advocate saying, "in FP, > you just ...". Any sentence that starts with "You just ..." > is suspicious :-) And why is that so? I mean: My screen has only N (finite number) lines. So more verbosity of that type actually diminishes by ability to have a clear view at the code. Brevity can be a boon. (I don't say it is always, but you can't dismiss it out of the hand). To me any sentence that effectively says: "Look I can do that in X, too" where X is something from {C, FORTRAN, Ada, Fortran, C++, Java, Lisp, Scheme} is suspicious. Because, as I tried to explain above, that is not the point: All languages are Turing complete. What really counts is HOW you do it. And especially the Ada community should know that, since Ada cannot do MORE things than C or C++: It only makes doing the same things less error prone, supposedly. > Can I have this without generics, please, Dmitry? ;-) :-)) hehe. Regards -- Markus