Functional Programming

Started by Charles Pegge, April 12, 2013, 02:42:24 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Charles Pegge

In a functional program:


General Rules

The statements are functions. (non imperative mode of expression)

functions can be passed and returned as parameters.  (functions are 'first class' entities).

functions return one item and affect nothing else (no side effects).

functions are immutable: for the same inputs the result will always be the same.

variables can only be assigned values once. (with the possible exception of counters and iterators).

recursion is a favoured means of achieving iteration without breaking the no-rewrite rule.

Advantages:

The Functions are thread-safe - concurrent execution
Programs can be formally proved
Greater possibilities for abstraction and reusabilty of components.
Greater scope for the compiler to optimise.

Disadvantages:

Less efficient than imperative programming.
Intensive gargage collection.
Major paradigm shift for most programmers


The question is: could you design a Windows GUI like this, without going into severe contortions :)


James C. Fuller

I gave Haskell a look-see many moons ago but as far as I can remember I had a difficult time getting my head around it.

James

Charles Pegge

I've skimmed over a few of these languages, and they do not seem to be intuitive. Perhaps they are to mathematicians, and computer science academics. The notation is often intimidating. But i'm intrigued by the concepts involved, which can be quite easily accommodated by more practical languages.

James C. Fuller

I found this interesting and am working my way through the examples with bc9 using gcc 4.8.0 which is C11 compliant.

http://msdn.microsoft.com/en-us/magazine/jj553512.aspx

James


John Spikowski

#4
QuoteThe question is: could you design a Windows GUI like this, without going into severe contortions.

I think IUP does a nice job taming the Windows API with their functional programming model. Your work with DLLC extends the concept to external functions but dynamically scripted at runtime. I think the DLLC super FFI interface will change how programming is done in the future. Using a core scripting language that can dynamically call any shared resource and only what functions and methods it needs with no compiling or linking reduces risk and support costs.

The SB/IUP/DLLC relationship is a unique paradigm. Once the IupMainLoop() starts, IUP takes over control and SB is only accessed to process callbacks, maintain the state of user defined variables and keeping channels open to shared resources.

P.S.

Thanks to the kind forum members that realize I'm not a witch.  (-18 and dropping)

James C. Fuller

Charles,
  Well I can't say I really understand it but here is my bc9 rendition of the Imutable example.
I added a new keyword "ref" which is used similar to ptr.
Could not get it to compile with MinGW.
James

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'Does not compile with MinGW
'added ref -> & to bc9 to handle &&
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
$CPPHDR
$NOMAIN
$ONEXIT "VC.BAT $FILE$ -m32 con"
'==============================================================================
Class Immutable
    private:
        Raw As double d_
        shared_ptr<std::string const> s_
    public:
        'Default constructor
        Constructor Immutable()
             d_=0.0
             s_ = std::make_shared<std::string const>("")
        End Constructor
'------------------------------------------------------------------------------       
        'Constructor taking a string
        Constructor Immutable(d As const double,s As const stdstr ref)
            d_ = d
            s_ = std::make_shared<std::string const>(s)
        End Constructor
'------------------------------------------------------------------------------       
        '// Move constructor
        Constructor Immutable(other As Immutable ref ref)
            std::swap(d_,other.d_)
            std::swap(s_,other.s_)
        End Constructor   
'------------------------------------------------------------------------------       
        'Move assignment operator
        Function operator= (other As Immutable ref ref) As Immutable ref
            std::swap(d_,other.d_)
            std::swap(s_,other.s_)
            Function =  *this
        End Function
'------------------------------------------------------------------------------       
        'Getter Functions
        Function GetD() As const double
            Function = d_
        End Function
'------------------------------------------------------------------------------
        Function GetS() As const stdstr Ref
            '// Return a const reference since string can be very large
            Function = *s_
        End Function
'------------------------------------------------------------------------------       
        '// "Setter" Functions (always return a new object)
        Function SetD(d As double) As Immutable const
            Immutable newObject(*this)
            newObject.d_ = d
            Function = newObject
        End Function
'------------------------------------------------------------------------------       
        Function SetS( s As const stdstr&) As Immutable const
            Immutable newObject(*this)
            newObject.s_ = std::make_shared<std::string const>(s)
            Function = newObject
        End Function
End Class
Sub Foo()
    '// Create an immutable object
    Raw As double d1 = 1.1
    Raw As stdstr s1 = "Hello World"
    Raw As Immutable a(d1, s1)
   
    '// Create a copy of the immutable object, share the data
    Immutable b(a)

    '// Create a new immutable object
    '// by changing an existing immutable object
    '// (Note the new object is returned
    Raw As stdstr s2 = "Hello Other"
    Raw As Immutable c = a.SetS(s2)
   
    '// Display the contents of each object
    cout << "a.GetD() = " << a.GetD() << ", " _
        << "a.GetS() = " << a.GetS() _
        << " [address = " << &(a.GetS()) << "]" << endl
    cout << "b.GetD() = " << b.GetD() << ", " _
        << "b.GetS() = " << b.GetS() _
        << " [address = " << &(b.GetS()) << "]" << endl
    cout << "c.GetD() = " << c.GetD() << ", " _
        << "c.GetS() = " << c.GetS() _
        << " [address = " << &(c.GetS()) << "]" << endl

End Sub 
'==============================================================================
FUNCTION main() As Integer
    Foo()
    pause
End Function



Charles Pegge

Thanks James,

I think the general idea is that once something has been created, the programmer is not allowed to change it. The responsibility for execution-order and the scope of values is then determined by the compiler and the OS.

The program could then be automatically distributed into several parallel-execution threads, sharing read-only data without restrictions.

Seems a good route to take for parallel computing.

Charles

Eduardo Jorge

interesting subject
have wondered where asm is needed nowadays with such rapid processing.
in data processing, games, statistics, ... in short, where you have to deal with a lot of data, or with a lot of analysis.
even interfaces where you have human intervention, are disgusting when things drag and are slow to update

with the computational advances, with many cores I think we have to have more tools and freedom for the programmer to decide where their processes can divide,