7 ms·
>Tada! Looks like you defined a new object. Then placed two objects into the the new object as dependencies. Sure You can call it composition. But that's not t
by crimsonalucard 7y ago
>Tada!
Looks like you defined a new object. Then placed two objects into the the new object as dependencies. Sure You can call it composition. But that's not the composition that I'm talking about. I specifically defined what I'm talking about in the first post so that it could be referred to rather than everyone needlessly going in circles talking about different definitions of composition. Here let me copy and paste it here for you as an example:
"The solution to incremental changes is to develop your app in a way where every unit of computation is compose-able under a strict rule. Meaning I can write a universal function compose(A,B) = C and that function can compose any primitive. Then you build complicated logic just like how you build a wall from a set of bricks... form complicated logic as a composition of more primitive logic all the way down."
Tada!
> Those aren't primitives, though. Primitives are the lowest possible level; that's what makes them primitives. If something can be decomposed further (or is in turn composed of other things which are visible to the language without e.g. dropping down to assembly), then it is definitionally not a primitive.
The lowest level primitive, you would think is a bit. But we hardly go to that level do we? We actually have higher level things that we refer to as primitives (for example ints). You know what's even lower than a bit? An electrical voltage... I can go to even lower levels of abstraction as well. Atoms. Yet here we are still calling a bit a primitive even though it is not the lowest level.
When you program you design systems. And in those systems you define primitives that function in YOUR universe. Sure you design the system on top of another system which in itself has lower level primitives but we don't have refer to those outside primitives within our own universe. So what I mean is primitives not in the sense of the system I am working in, but in the system I am creating.
That being said. PRIMITIVE is 100% the appropriate word. You never defined what you mean by component but I'm sure it's some super specific thing that comes from some design pattern, but that's besides the point.
>That's a circular definition, and does not in any way clarify what you mean by "procedures".
You're referring to a typo. Replace "of" with "or" the point was to illustrate a potential refactoring. Ex: A list of procedures is the same as a list of instructions.
You get what I mean by procedures so no need to act confused about my typo or a slightly confusingly worded sentence.
>In pseudo-Forth (with punctuation turned into something more reasonable, and a couple imaginary procedures for creating (anonProcedure) and executing (execute) function pointers):
We can get really technical here. Due to Curry howard isomorphism a turing machine can technically do anything and simulate composition as well. But like your example shows, it is awkward. It's adding a char to an int in C++. Yeah you can do it.
Additionally you are arbitrarily naming your procedures. Step 6 should be something that is very distant in meaning from step 1. For example:
Step 1 should be go to store.
Step 2 should be buy chicken.
Steps 3-5 should be all the steps to prepare the chicken.
Step 6 is eat chicken
Compose step 1 with step 6. It does not make semantic sense.
Go to store, eat chicken.
What chicken?
Sure you can "compose" but like I said, you've basically gave an example where you can do anything. You need rules on what can compose with what. Usually these rules are implemented by something called a type system. Type systems are typically ineffective at enforcing composition of procedures. There would really be no way for a type system in your example to make sure step 1 can only compose with step 2 to form stepOneAndTwo and such a composition is not universally defined. You define how your steps compose on every program you write. No legos, no modularity.
>Maybe you'd do a better job conveying your point if you just said the "primitive" you mean instead of being needlessly coy about it.
I'm not being coy. What's going on here is an inability to understand. Or maybe you do understand. In that case I don't know what's going on.
>And regarding this brick-which-cannot-be-named-for-some-reason: yes, they happen to snap together remarkably well like Lego bricks, but people don't (typically) build their houses with Lego bricks, nor do people normally write their business logic in Haskell.
What does haskell have to do with this? I'm not talking about haskell. I am talking about something 100% of all programmers already use all the time.
I'm not naming the brick because if you know what I'm talking about, then there's really no point in arguing about it is there? You get it, because the logic led inescapably to one place. You arrived at the same conclusion and therefore we are in agreement.
If you don't get it, well that's not my problem, I'm not here to dive into a rabbit hole about the merits of a certain topic, only the flaws of the current paradigm. You want to talk about it? be my guest, I'm not starting it myself.
Who writes business logic in Forth nowadays? Less people than haskell that's 100% fact, but that's besides the point because, again, I never was talking about haskell.
- yellowapple 7y ago> But that's not the composition that I'm talking about. Okay, then: composeObjects(first, second) = { third = new Object third._methods = first._methods.merge(second._methods) return third } class Foo { hi = { puts "howdy" } } class Bar { bye = { puts "adios" } } baz = composeObjects(new Foo, new Bar) baz.hi # prints "howdy" baz.bye # prints "adios" Tada! This is only slightly simplified from languages like, say, Ruby or Common Lisp, both of which (last I checked) support this sort of class-oriented metaprogramming (or Perl, which exposes the ability to "bless" arbitrary data structures as objects). > But like your example shows, it is awkward. In what way was that especially awkward? You take two pointers to already-compiled procedures, you jump to / call those addresses one after the other, and Tada! you've got literally all that's required to build one procedure dynamically from two different ones. > Go to store, eat chicken. > What chicken? That depends on your domain. In this particular case, it could be the first chicken on the stack. It won't be a particularly tasty chicken, since it'll be entirely uncooked and probably frozen, but that's certainly within the realm of possibility. > you've basically gave an example where you can do anything Well yeah, welcome to Turing-completeness :) > You need rules on what can compose with what. Indeed, and the rules in that example would be: 1. There are two things on the stack, and those things are addresses of procedures to JMP or CALL into. That's really all there is to it. If the arguments aren't valid pointers to procedures, then you crash :) (There are of course Forth derivatives/dialects/descendants that do type checking, in which case you could verify that the two topmost items on the stack are pointers to procedures, but that's not strictly necessary for composition; just for making sure your composition procedure doesn't try to compose things that aren't procedures) > Who writes business logic in Forth nowadays? I picked Forth (or more specifically: an imaginary derivative thereof) for the procedure-composition example because it's simple to a fault, and because it's able to compile procedures at runtime. You pop things from the stack, you push things onto the stack. You pop two pointers, you store them in the necessary code to CALL or JMP to those pointers, and you push a pointer to that generated code. Tada! Composed. You could do the same thing in Lisp, or in C/C++ (when linked to, say, LLVM, or when using a compiler that allows dropping down to assembly), or assembly, or in quite literally any other Turing-complete language with the ability to emit arbitrary code and JMP to it (and even then). Again: not all bricks are Legos. Nothing wrong with needing mortar and rebar to build something.