Why does Smalltalk support first class functions, but not other functional features? - oop

An answer to Is Javascript a Functional Programming Language? said that:
Functional programming means that the program is conceptualized as a evaluation of a function, rather than a control flow. The code is a description of functions, and has no inherent concept of a control flow.
I've learnt that when a language supported first class functions, and had no control flows, from its design objective, it must be defined as a functional language.
So why does Smalltalk, a functional language, not support other functional features, such as immutability, algebraic data types, pattern matching, partial application?

Smalltalk was designed on top of the following features provided by the Virtual Machine
Object allocation: The #basicNew and #basicNew: primitives
Automatic deallocation: The GC
Message sends: The send family of bytecodes
Blocks: The [:arg | ...] syntax (see below)
Non-local returns: The [:arg | ... ^result] syntax
Late binding: The method lookup mechanism
Native code compilation: The interpreter (see below)
Modern implementations added
Block Closures: Which replaced blocks
Fast compilation: The JIT compiler, which replaced the interpreter
Stack unwind: The #ensure: message
Note that other "features" such as the Smalltalk Compiler, the Debugger or the Exception mechanism are not in the list because they can be derived from others (i.e., they are implemented in user code.)
These features where identified as the fundamental building blocks for a general purpose Object Oriented environment meant to run on the bare metal (i.e. with no Operating System support.)
What the designers had in mind wasn't Functional Programming. Instead they had in mind the every thing is an object and every computation is a message send uniform metaphor. To this end, blocks and non-local returns played the role of modeling "functions" as objects too so to make sure that every known concept got included in the OO paradigm. This doesn't mean that they had functional programming as a goal. They didn't include other features (functional or not) because they were trying to identify a minimal set of primitive elements that would support a general purpose system with no hindrances.

Related

How is it possible to have a purely object-oriented language?

Java is considered an OOP language, despite it not quite being purely OOP. Java contains 8 primitives, and in an interview, James Gosling explains why:
Bill Venners: Why are there primitive types in Java? Why wasn't
everything just an object?
James Gosling: Totally an efficiency thing. There are all kinds of
people who have built systems where ints and that are all objects.
There are a variety of ways to do that, and all of them have some
pretty serious problems. Some of them are just slow, because they
allocate memory for everything. Some of them try to do objects where
sometimes they are objects, sometimes they are not (which is what the
standard LISP system did), and then things get really weird. It kind
of works, but it's strange.
So it seems that both memory and speed are issues that Java's primitives solve. However, this got me wondering how can a language be true, pure object-oriented?
If only a byte primitive existed, you could build from there. Creating integers, chars and eventually floats and doubles. But without any base structure at all, how could you build anything? Isn't at least some base primitive necessary? In other words, isn't a base data-structure needed in to expand from?
If you're asking if there are languages that have no way to interact with primitive types, then you might want to look at something like Scala. From that page:
Scala is a pure object-oriented language in the sense that every value is an object.
However, as you point out (for Kotlin):
the compiler maps them to JVM primitives when at all possible to save memory
If your definition of what object-oriented languages can be requires that everything is always represented as an object, then a purely object-oriented language is impossible. You can't build a language that runs on a real computer that only has objects. This is because the computer must have a way to represent the data natively. This is essentially what primitives in object-oriented languages are: The native forms of data that the underlying computer (or VM) can represent. No matter what you do, you will always need to have some non-object representation of data in order for the computer to do operations with it. Even if you built a JavaScript interpreter that really represented primitives as objects, in order to add two integers, the interpreter would have to have load the integers into CPU registers and use some form of an add instruction.
But that explanation sort of misses the point of object-oriented programming. A programming language is not the same as a program. Languages are just a tool for us to make computers do what we want - they don't actually exist at runtime. You would probably say that a program written in Kotlin or Scala is more object-oriented than a program written in C, despite both languages compiling to the same assembly instructions at runtime.
So, if you relax your definition of pure object-oriented programming to no longer be concerned with what the runtime representation of data is, then you'll find that purely object-oriented languages are possible. When programming Scala, you never interact with anything that's not an object. Even if your Int becomes a 'primitive' at runtime, it doesn't really matter, because you, as the programmer, never really have to think about that (at least, in an ideal world where performance and memory never matter). The language definition of Scala doesn't include the concept of primitives at all - they are part of the implementation of the language, not the language itself.
As far your example of Java goes, Java probably isn't a purely object-oriented language by most definitions. It is, however, mostly object-oriented. Java is often mentioned as the de facto object oriented language because it was much more object oriented than what came before it.
Even further, the term object-oriented doesn't really have a definitive meaning. To some people it might mean that everything has to be an object, and to others it might just mean that there need to be objects, some definitions require the concept of classes, some don't, etc.

Is object-orientated programming compatible with functional programming?

I grew up being taught java, and I've started to learn a lot of PHP over the last few years using popular open-source CMSs. I really love the natural-feeling of OOP, but I've more recently discovered the concept of functional programming, which appears to be a difficult but elegant way of doing things.
In rtperson's great answer to the question "What is functional, declarative and imperative programming? [closed]", he says that "Then there's Object-oriented programming, which is really just a new way to organize data in an imperative program."
I think I understand what he means by that, but is it strictly true? Can OOP co-exist with functional programming?
Yes, there is a term of "object functional programming".
Basically in those languages a function is a "first class citizen" - an object.
I guess most agree it is not so easy to get there just because you have to know about all concepts - functional, OO and imperative.
Examples for such languages are:
Scala (I like it very much)
Boost::function , Boost::bind in C++
.NET F#
javascript (aka ECMAScript)
Yes it's compatible. You can program in a functional way in any language. An example would be Java String which is immutable and returns a new object if you do altering methods such as change case etc.
If you think about it o.something(y) is just osomething(o, y) and if you don't mutate o or do other side effects not related to OO it's functional.
Yes. There is something called a 'functional object', which is basically an object where the mutator methods, instead of changing the state of the object, return a new object with modified state. Clean combines that idea with uniqueness types to keep the modified states single-threaded, which allows the compiler to implement methods by modifying the storage for the object behind the scenes.
Furthermore, there's nothing about mutable state that makes it 'not purely functional'; what's impure is when ordinary expression evaluation mutates state that's visible to the program. So you can combine OO and purely functional programming by making your object's methods return actions in the IO monad (or any other stateful monad) that mutate a common set of underlying state (not available to the rest of the program).

Achieving polymorphism in functional programming

I'm currently enjoying the transition from an object oriented language to a functional language. It's a breath of fresh air, and I'm finding myself much more productive than before.
However - there is one aspect of OOP that I've not yet seen a satisfactory answer for on the FP side, and that is polymorphism. i.e. I have a large collection of data items, which need to be processed in quite different ways when they are passed into certain functions. For the sake of argument, let's say that there are multiple factors driving polymorphic behaviour so potentially exponentially many different behaviour combinations.
In OOP that can be handled relatively well using polymorphism: either through composition+inheritance or a prototype-based approach.
In FP I'm a bit stuck between:
Writing or composing pure functions that effectively implement polymorphic behaviours by branching on the value of each data item - feels rather like assembling a huge conditional or even simulating a virtual method table!
Putting functions inside pure data structures in a prototype-like fashion - this seems like it works but doesn't it also violate the idea of defining pure functions separately from data?
What are the recommended functional approaches for this kind of situation? Are there other good alternatives?
Putting functions inside pure data structures in a prototype-like fashion - this seems like it works but doesn't it also violate the idea of defining pure functions separately from data?
If virtual method dispatch is the way you want to approach the problem, this is a perfectly reasonable approach. As for separating functions from data, that is a distinctly non-functional notion to begin with. I consider the fundamental principle of functional programming to be that functions ARE data. And as for your feeling that you're simulating a virtual function, I would argue that it's not a simulation at all. It IS a virtual function table, and that's perfectly OK.
Just because the language doesn't have OOP support built in doesn't mean it's not reasonable to apply the same design principles - it just means you'll have to write more of the machinery that other languages provide built-in, because you're fighting against the natural spirit of the language you're using. Modern typed functional languages do have very deep support for polymorphism, but it's a very different approach to polymorphism.
Polymorphism in OOP is a lot like "existential quantification" in logic - a polymorphic value has SOME run-time type but you don't know what it is. In many functional programming languages, polymorphism is more like "universal quantification" - a polymorphic value can be instantiated to ANY compatible type its user wants. They're two sides of the exact same coin (in particular, they swap places depending on whether you're looking at a function from the "inside" or the "outside"), but it turns out to be extremely hard when designing a language to "make the coin fair", especially in the presence of other language features such as subtyping or higher-kinded polymorphism (polymorphism over polymorphic types).
If it helps, you may want to think of polymorphism in functional languages as something very much like "generics" in C# or Java, because that's exactly the type of polymorphism that, e.g., ML and Haskell, favor.
Well, in Haskell you can always make a type-class to achieve a kind of polymorphism. Basically, it is defining functions that are processed for different types. Examples are the classes Eq and Show:
data Foo = Bar | Baz
instance Show Foo where
show Bar = 'bar'
show Baz = 'baz'
main = putStrLn $ show Bar
The function show :: (Show a) => a -> String is defined for every data type that instances the typeclass Show. The compiler finds the correct function for you, depending on the type.
This allows to define functions more generally, for example:
compare a b = a < b
will work with any type of the typeclass Ord. This is not exactly like OOP, but you even may inherit typeclasses like so:
class (Show a) => Combinator a where
combine :: a -> a -> String
It is up to the instance to define the actual function, you only define the type - similar to virtual functions.
This is not complete, and as far as I know, many FP languages do not feature type classes. OCaml does not, it pushes that over to its OOP part. And Scheme does not have any types. But in Haskell it is a powerful way to achieve a kind of polymorphism, within limits.
To go even further, newer extensions of the 2010 standard allow type families and suchlike.
Hope this helped you a bit.
Who said
defining pure functions separately from data
is best practice?
If you want polymorphic objects, you need objects. In a functional language, objects can be constructed by glueing together a set of "pure data" with a set of "pure functions" operating on that data. This works even without the concept of a class. In this sense, a class is nothing but a piece of code that constructs objects with the same set of associated "pure functions".
And polymorphic objects are constructed by replacing some of those functions of an object by different functions with the same signature.
If you want to learn more about how to implement objects in a functional language (like Scheme), have a look into this book:
Abelson / Sussman: "Structure and Interpration of Computer programs"
Mike, both your approaches are perfectly acceptable, and the pros and cons of each are discussed, as Doc Brown says, in Chapter 2 of SICP. The first suffers from having a big type table somewhere, which needs to be maintained. The second is just traditional single-dispatch polymorphism/virtual function tables.
The reason that scheme doesn't have a built-in system is that using the wrong object system for the problem leads to all sorts of trouble, so if you're the language designer, which to choose? Single despatch single inheritance won't deal well with 'multiple factors driving polymorphic behaviour so potentially exponentially many different behaviour combinations.'
To synopsize, there are many ways of constructing objects, and scheme, the language discussed in SICP, just gives you a basic toolkit from which you can construct the one you need.
In a real scheme program, you'd build your object system by hand and then hide the associated boilerplate with macros.
In clojure you actually have a prebuilt object/dispatch system built in with multimethods, and one of its advantages over the traditional approach is that it can dispatch on the types of all arguments. You can (apparently) also use the heirarchy system to give you inheritance-like features, although I've never used it, so you should take that cum grano salis.
But if you need something different from the object scheme chosen by the language designer, you can just make one (or several) that suits.
That's effectively what you're proposing above.
Build what you need, get it all working, hide the details with macros.
The argument between FP and OO is not about whether data abstraction is bad, it's about whether the data abstraction system is the place to stuff all the separate concerns of the program.
"I believe that a programming language should allow one to define new data types. I do not believe that a program should consist solely of definitions of new data types."
http://www.haskell.org/haskellwiki/OOP_vs_type_classes#Everything_is_an_object.3F nicely discusses some solutions.

OOP vs procedural in run-time

I have very simple question I cant find answer anywhere on the internet.
So, my question is, in procedural programming, code is in code section, which goes into Read Only memory area. Variables are either on stack or heap.
But OOP says that object are created in memory. So, does it mean even functions are written into R/W memory area?
And, does Os have to have some inbuilt OOP programs support? For example if OS doesent allowed to read instruction outside Read only code section. Thanks.
Generally, both OOP and procedural programming are abstractions which exist only at the source-code level. Once a program is compiled into executable machine-code, these abstractions cease to exist. So whether or not a particular language is OOP or procedural has no bearing on what regions of memory it uses, or where instructions are placed during execution.
The OS itself usually doesn't know or care whether a particular executable was written in an OOP or procedural language. It only cares that the executable uses binary op-codes compatible with its native instruction set, and that the executable has an ABI (binary interface) that it understands.
This is a good question.
Whereas as object constitutes functions and data as being placed in the same spot theoretically, most implementations split it. The way you do it, is that code is split out and stored into the RO segment. An object in the RW area then have a way to refer back to that code in the RO area. The coupling of code and data is only used conceptually by the human programmer and the type checker to ensure that you do not violate the rules and principles.
A Java/C#-like language will usually be made such that each object has a tag identifying the type of the object. The object itself is simply a struct containing all the fields laid out in a prespecified order. This tag can then be used to look up which function in the RO-area to call. The function in the RO-area is altered to take an extra parameter, called this or self through which the contents of said object can be reached. When the method needs to refer to fields, it knows the pre-specified order, so it can do that correclty. Note that there are some tricks needed to solve inheritance, but this is the crux of the idea.
A Python/Ruby-like language will usually make an object be a hash-table where a method is a pointer to the code in the RO-area (provided that the language is compiled and not run through a bytecode interpreter). Function calls are made by looking up the hash-table contents and following the code pointer. Fields are also looked up in the same hash table.
With those basics down, most implementations make tricks to avoid the part where a pointer is followed to find the function to call. They try to figure out and narrow down the possible call to a single function. Then they can replace the lookup with a direct call to the right function, a much faster solution.
the tl;dr version: The language semantics views fields and methods as part of an object. The implementation split them into RO and RW segments. As such no OS support is needed.
OOP doesn't say this. I have no idea where you read it, if you add a quote that would help.
Objects are variables, so what you know about variables is correct for objects. In languages like C# (.net framework actually) objects can only be stored in heap, because they are so called reference types. In C++ they can live anywhere.
But OOP says that object are created in memory. So, does it mean even functions are written into R/W memory area?
From this i concluded that you think that functions are objects. That is true in far not every OOP language. It is from functional languages where functions are first class objects. Functions are in majority of cases immutable and are placed in read only sections.
Common OSes like Windows, Linux and MacOsx are unaware of objects. This is purely program concept. .net framework and java vm provide layer of abstraction. They are execution environments that have build in object support.

What are possible designs for the DCI architecture?

What are possibles designs for implementation of the DCI (data, contexts, interactions) architecture in different OOP languages? I thought of Policy based design (Andrei Alexandrescu) for C++, DI and AOP for Java. However, I also thought about using State design pattern for representing roles and some sort of Template method for the interactions... What are the other possibilities?
Doing pure DCI is tough in most language you usually run into one of two problems. Statically typed languages such as Java usually ends up with some kind of wrapper solution which creates a self schizofrenia problem. Dynamic languages that let you attach new instance methods at will at run time often suffers from a scoping issue. The RoleMethods are still available when the object is no longer playing the role.
Best fits I know of for different languages
Marvin: Design for DCI and as such has full support
Ruby using Maroon. If you are using the maroon gem (or similar) then there's full support for DCI in Ruby.
Java: Qi4J
C# Extension methods (Scoping issue and overload issue) possibly together with dynamic. I've had an implementation based on Clay but that creates an identity problem
Native Ruby: Method injection Scoping issue with methods being available when the object no longer plays the role
C++: Templates. Scoping issue method life span is the same as the object life span
if you take a look at fullOO you will find examples in a few languages. Including in my own project Marvin which is a language specifically designed to support DCI. At present most of Marvin is identical to C# so you could say it's an extension to C# more than a language of it's own right.
In Java, without byte-code generation, I would use Decorator pattern for contexts, however I will instead of classes decorate interfaces, which will be more flexible. Data than will be represented through classes implementing the interfaces. The interactions will be done using manual dependency injection into Template methods.