SlideShare a Scribd company logo
Functional Smalltalk
Dave Mason
Toronto Metropolitan University
©2022 Dave Mason
Value
I’m going to start with a quote from Kent Beck
Value
Software creates value 2 ways:
What it does today
What new things we can make it do tomorrow
Value
Software creates value 2 ways:
What it does today
What new things we can make it do tomorrow
Value
Software creates value 2 ways:
What it does today
What new things we can make it do tomorrow
Value
Smalltalk creates value 2 ways:
What it does today
What new things we can make it do tomorrow
Functional Smalltalk
Smalltalk already has many functional features
extensions by syntax
extensions by class
Functional Smalltalk
Smalltalk already has many functional features
extensions by syntax
extensions by class
Syntax: Functional Programming
Smalltalk has always had blocks - needed full closures
CompileWithCompose in Pharo-Functional repo
leverages class-bounded alternative compiler
just syntactic sugar - more succinct
all are upward compatible as they are currently syntax errors
Syntax: Functional Programming
Smalltalk has always had blocks - needed full closures
CompileWithCompose in Pharo-Functional repo
leverages class-bounded alternative compiler
just syntactic sugar - more succinct
all are upward compatible as they are currently syntax errors
Syntax: Functional Programming
Smalltalk has always had blocks - needed full closures
CompileWithCompose in Pharo-Functional repo
leverages class-bounded alternative compiler
just syntactic sugar - more succinct
all are upward compatible as they are currently syntax errors
Syntax: Functional Programming
Smalltalk has always had blocks - needed full closures
CompileWithCompose in Pharo-Functional repo
leverages class-bounded alternative compiler
just syntactic sugar - more succinct
all are upward compatible as they are currently syntax errors
Syntax: Functional Programming
Smalltalk has always had blocks - needed full closures
CompileWithCompose in Pharo-Functional repo
leverages class-bounded alternative compiler
just syntactic sugar - more succinct
all are upward compatible as they are currently syntax errors
Compose/pipe/parrot operator
very convenient to pass result of one expression to another
without parentheses
particularly convenient in PharoJS for e.g. D3
Compose/pipe/parrot operator
very convenient to pass result of one expression to another
without parentheses
particularly convenient in PharoJS for e.g. D3
1 foo
2 " s e l f new foo >>> 42 "
3 ↑ 17 negated
4 :> min: -53
5 :> abs
6 :> < 100
7 :> and: [ 4 > 2 ]
8 :> and: [ 5 < 10 ]
9 :> ifTrue: [ 42 ] ifFalse: [ 99 ]
Compose/pipe/parrot operator
very convenient to pass result of one expression to another
without parentheses
particularly convenient in PharoJS for e.g. D3
1 foo
2 " s e l f new foo >>> 42 "
3 ↑ 17 negated
4 :> min: -53
5 :> abs
6 :> < 100
7 :> and: [ 4 > 2 ]
8 :> and: [ 5 < 10 ]
9 :> ifTrue: [ 42 ] ifFalse: [ 99 ]
... Compose/pipe/parrot operator
The precedence is the same as cascade, so you can intermix them
and could say something like:
1 x := OrderedCollection new
2 add: 42;
3 add: 17;
4 yourself
5 :> collect: #negated
6 :> add: 35;
7 add: 99;
8 yourself
9 :> with: #(1 2 3 4) collect: [:l :r| l+r ]
10 :> max
... Compose/pipe/parrot operator
If you don’t want to use the alternate compiler (and get the :> syntax)
PharoFunctional also provides a chain method on Object that
supports chaining using cascades (unfortunately quite a bit slower
because it requires a DNU and perform for each chained message):
1 foo
2 " s e l f new foo >>> 42 "
3 ↑ 17 chain
4 negated
5 ; min: -53
6 ; abs
7 ; < 100
8 ; and: [ 4 > 2 ]
9 ; and: [ 5 < 10 ]
10 ; ifTrue: [ 42 ] ifFalse: [ 99 ]
Point-free programming style
popular style of functional programming
composing functions to build up operations with implicit
parameters
various “combinators” that recognize patterns in these
compositions
in Smalltalk this is composing symbols and blocks
e.g.
1 isPalindrome := #reverse <| > #= .
2 isPalindrome value: ’madam’
Point-free programming style
popular style of functional programming
composing functions to build up operations with implicit
parameters
various “combinators” that recognize patterns in these
compositions
in Smalltalk this is composing symbols and blocks
e.g.
1 isPalindrome := #reverse <| > #= .
2 isPalindrome value: ’madam’
Point-free programming style
popular style of functional programming
composing functions to build up operations with implicit
parameters
various “combinators” that recognize patterns in these
compositions
in Smalltalk this is composing symbols and blocks
e.g.
1 isPalindrome := #reverse <| > #= .
2 isPalindrome value: ’madam’
Point-free programming style
popular style of functional programming
composing functions to build up operations with implicit
parameters
various “combinators” that recognize patterns in these
compositions
in Smalltalk this is composing symbols and blocks
e.g.
1 isPalindrome := #reverse <| > #= .
2 isPalindrome value: ’madam’
Point-free programming style
popular style of functional programming
composing functions to build up operations with implicit
parameters
various “combinators” that recognize patterns in these
compositions
in Smalltalk this is composing symbols and blocks
e.g.
1 isPalindrome := #reverse <| > #= .
2 isPalindrome value: ’madam’
Expressions as unary or binary messages
To use point-free style, it is very convenient to have a more succinct
syntax for applying them
1 x (...)
2 x (...) + y
3 x (...): y
4 x (#sort <| > #=)
Converts to.
1 ([...] value: x)
2 ([...] value: x) + y
3 ([...] value: x value: y)
4 ((#sort <| > #=) value: x)
Blocks as unary or binary messages
You can do the same with unary or binary blocks. Because we know
the arity of blocks the trailing : isn’t used for block operators
1 x [:w| ...]
2 x [:w:z| ...] y
becomes
1 ([:w| ...] value: x)
2 ([:w:z| ...] value: x value: y)
Initializing local variables at point of declaration
Even in functional languages where mutation is possible, it is rarely
used. Instead programming is by a sequence of definitions, which
always have a value. I personally very much miss this in Smalltalk.
1 | w x := 42. y = x+5. z a |
is legal, but
1 | x := 42. y = x+5. z = 17 |
isn’t.
Collection literals
Arrays have a literal syntax {1 . 2 . 3}, but other collections don’t.
This extension recognizes :className immediately after the { and
translates, e.g.
1 {:Set 3 . 4 . 5 . 3}
2 {:Dictionary #a->1 . #b->2}
3 {:Set 1 . 2 . 3 . 4 . 5 . 6 . 7}
to
1 Set with: 3 with: 4 with: 5 with: 3
2 Dictionary with: #a->1 with: #b->2
3 Set withAll: {1 . 2 . 3 . 4 . 5 . 6 . 7}
Destructuring collections
There isn’t a convenient way to return multiple values from a method,
or even to extract multiple values from a collection. For example:
1 :| a b c | := some-collection
destructures the 3 elements of a SequenceableCollection or would
extract the value of keys #a #b etc. if it was a Dictionary, with anything
else being a runtime error. This is conveniently done by converting that
to:
1 ([:temp|
2 a := temp firstNamed: #a.
3 b := temp secondNamed: #b.
4 c := temp thirdNamed: #c.
5 temp] value: some-collection)
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Classes: Functional Programming
PharoFunctional adds several new classes and a variety of extension
methods to facilitate functional programming.
curry: and @@
value:, value:value: and cull, etc. for Symbol
map:, map:map: for BlockClosure and Symbol
<*> and other combinators for BlockClosure and Symbol
nilOr:, emptyOrNilOr:
Slice, Pair and Tuple, ZippedCollection
zip:, >===<
iota
many algorithms on collections: rotate:, slide:, product,
allEqual, unique, isUnique, groupByRunsEqual:,
groupByRunsTrue:
Demo
Using CompileWithCompose
1 Metacello new
2 baseline: ’PharoFunctional’;
3 repository: ’github://dvmason/Pharo-Functional:ma
4 load: #compiler
Then for any class heirarchy, add a trait:
1 RBScannerTest subclass: #ComposeExampleTest
2 uses: ComposeSyntax
3 instanceVariableNames: ’’
4 classVariableNames: ’’
5 package: ’CompileWithCompose-Tests’
Or, on the class-side define the following method:
1 compilerClass
2 " Answer a compiler c l a s s a p p r o p r i a t e f o r source
3 ↑ ComposeCompiler
You can use this second approach if you want to add it to the entire
image (including in playgrounds), by defining this in Object class.
Conclusions
Smalltalk already has the fundamentals for functional
programming
some simple syntactic suger can make it a lot more pleasant
I would love it if some of these became mainstream (with no
backward compatibility issues)
in the meantime, anyone can add this to their Pharo
the compiler tweaks are not hard for other Smalltalks to implement
Conclusions
Smalltalk already has the fundamentals for functional
programming
some simple syntactic suger can make it a lot more pleasant
I would love it if some of these became mainstream (with no
backward compatibility issues)
in the meantime, anyone can add this to their Pharo
the compiler tweaks are not hard for other Smalltalks to implement
Conclusions
Smalltalk already has the fundamentals for functional
programming
some simple syntactic suger can make it a lot more pleasant
I would love it if some of these became mainstream (with no
backward compatibility issues)
in the meantime, anyone can add this to their Pharo
the compiler tweaks are not hard for other Smalltalks to implement
Conclusions
Smalltalk already has the fundamentals for functional
programming
some simple syntactic suger can make it a lot more pleasant
I would love it if some of these became mainstream (with no
backward compatibility issues)
in the meantime, anyone can add this to their Pharo
the compiler tweaks are not hard for other Smalltalks to implement
Conclusions
Smalltalk already has the fundamentals for functional
programming
some simple syntactic suger can make it a lot more pleasant
I would love it if some of these became mainstream (with no
backward compatibility issues)
in the meantime, anyone can add this to their Pharo
the compiler tweaks are not hard for other Smalltalks to implement
Questions?
@DrDaveMason dmason@ryerson.ca
https://github.com/dvmason/Pharo-Functional

More Related Content

PDF
Bloc for Pharo: Current State and Future Perspective
 
PDF
How Fast is AI in Pharo? Benchmarking Linear Regression
 
PDF
Design Principles for a High-Performance Smalltalk
 
PDF
Application Development with Pharo
 
PDF
Pharo Virtual Machine: News from the Front
 
PDF
Pharo 10 and beyond
 
PDF
Pharo foreign function interface (FFI) by example by Esteban Lorenzano
 
PDF
Applications in Pharo
 
Bloc for Pharo: Current State and Future Perspective
 
How Fast is AI in Pharo? Benchmarking Linear Regression
 
Design Principles for a High-Performance Smalltalk
 
Application Development with Pharo
 
Pharo Virtual Machine: News from the Front
 
Pharo 10 and beyond
 
Pharo foreign function interface (FFI) by example by Esteban Lorenzano
 
Applications in Pharo
 

What's hot (20)

PDF
GemStone Update
 
PDF
PharoJS: Hijack the JavaScript Ecosystem
 
PDF
Improving Pharo Snapshots
 
PDF
PharoJS: Pharo-Based TDD for Javascript Applications
 
PPTX
Apache Flink Hands On
PDF
Pharo, Spec and GTK
 
PDF
é–ąæ•°ăƒ—ăƒ­ă‚°ăƒ©ăƒŸăƒłă‚°ć…„é–€
PDF
No drama here - E2E-testing django with playwright
PPTX
ă€Œæ›žă‘ă‚‹ă€ă‹ă‚‰ă€Œă§ăă‚‹ă€ă«ăȘă‚Œă‚‹ïŒ JavaュヹăƒȘçŻ€çŽ„ăƒŽă‚Šăƒă‚Šè©±ïœž
PDF
Boost.ć‹‰ćŒ·äŒš #21 札ćčŒă€ŒC++1zにstring_viewăŒć°Žć…„ă•ă‚ŒăŠă†ă‚Œă—ă„ăźă§çŽčä»‹ă—ăŸă™ă€
PPTX
Cruiser: A Tool to Package Pharo Applications
 
PDF
[2012 대학íŠč강] 아티슀튞 + í”„ëĄœê·žëž˜ëšž
PPTX
Parallel Futures of a Game Engine (v2.0)
 
KEY
Big Data in Real-Time at Twitter
PDF
Heap exploitation
PDF
30 Symfony Best Practices
PDF
Quartzど゙cronを範ć›Čæ€œçŽąă—ăŸă„
PPTX
page replacement.pptx
PPTX
Killzone Shadow Fall: Threading the Entity Update on PS4
 
PDF
OSSNA 2017 Performance Analysis Superpowers with Linux BPF
GemStone Update
 
PharoJS: Hijack the JavaScript Ecosystem
 
Improving Pharo Snapshots
 
PharoJS: Pharo-Based TDD for Javascript Applications
 
Apache Flink Hands On
Pharo, Spec and GTK
 
é–ąæ•°ăƒ—ăƒ­ă‚°ăƒ©ăƒŸăƒłă‚°ć…„é–€
No drama here - E2E-testing django with playwright
ă€Œæ›žă‘ă‚‹ă€ă‹ă‚‰ă€Œă§ăă‚‹ă€ă«ăȘă‚Œă‚‹ïŒ JavaュヹăƒȘçŻ€çŽ„ăƒŽă‚Šăƒă‚Šè©±ïœž
Boost.ć‹‰ćŒ·äŒš #21 札ćčŒă€ŒC++1zにstring_viewăŒć°Žć…„ă•ă‚ŒăŠă†ă‚Œă—ă„ăźă§çŽčä»‹ă—ăŸă™ă€
Cruiser: A Tool to Package Pharo Applications
 
[2012 대학íŠč강] 아티슀튞 + í”„ëĄœê·žëž˜ëšž
Parallel Futures of a Game Engine (v2.0)
 
Big Data in Real-Time at Twitter
Heap exploitation
30 Symfony Best Practices
Quartzど゙cronを範ć›Čæ€œçŽąă—ăŸă„
page replacement.pptx
Killzone Shadow Fall: Threading the Entity Update on PS4
 
OSSNA 2017 Performance Analysis Superpowers with Linux BPF
Ad

Similar to Functional Smalltalk (20)

KEY
Pharo, an innovative and open-source Smalltalk
PDF
Functional programming in ruby
PDF
Functional Programming for Busy Object Oriented Programmers
PDF
7li7w devcon5
PDF
Functional Programming in F#
PDF
2013 lecture-02-syntax shortnewcut
 
PDF
Peyton jones-2011-type classes
PDF
OOP and FP
PDF
On Functional Programming - A Clojurian Perspective
PPTX
Introduction to Clojure and why it's hot for Sart-Ups
 
PDF
The Pharo Programming Language
 
PDF
Pharo: Objects at your Fingertips
 
PDF
Clojure intro
PDF
Pune Clojure Course Outline
PDF
Elixir & Phoenix – fast, concurrent and explicit
PDF
F# and Reactive Programming for iOS
PDF
ScotRuby - Dark side of ruby
KEY
LISP: How I Learned To Stop Worrying And Love Parantheses
PDF
Intro to Functional Programming
PDF
FSharp Talk
Pharo, an innovative and open-source Smalltalk
Functional programming in ruby
Functional Programming for Busy Object Oriented Programmers
7li7w devcon5
Functional Programming in F#
2013 lecture-02-syntax shortnewcut
 
Peyton jones-2011-type classes
OOP and FP
On Functional Programming - A Clojurian Perspective
Introduction to Clojure and why it's hot for Sart-Ups
 
The Pharo Programming Language
 
Pharo: Objects at your Fingertips
 
Clojure intro
Pune Clojure Course Outline
Elixir & Phoenix – fast, concurrent and explicit
F# and Reactive Programming for iOS
ScotRuby - Dark side of ruby
LISP: How I Learned To Stop Worrying And Love Parantheses
Intro to Functional Programming
FSharp Talk
Ad

More from ESUG (20)

PDF
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
 
PDF
Micromaid: A simple Mermaid-like chart generator for Pharo
 
PDF
Directing Generative AI for Pharo Documentation
 
PDF
Even Lighter Than Lightweiht: Augmenting Type Inference with Primitive Heuris...
 
PDF
Composing and Performing Electronic Music on-the-Fly with Pharo and Coypu
 
PDF
Gamifying Agent-Based Models in Cormas: Towards the Playable Architecture for...
 
PDF
Analysing Python Machine Learning Notebooks with Moose
 
PDF
FASTTypeScript metamodel generation using FAST traits and TreeSitter project
 
PDF
Migrating Katalon Studio Tests to Playwright with Model Driven Engineering
 
PDF
Package-Aware Approach for Repository-Level Code Completion in Pharo
 
PDF
Evaluating Benchmark Quality: a Mutation-Testing- Based Methodology
 
PDF
An Analysis of Inline Method Refactoring
 
PDF
Identification of unnecessary object allocations using static escape analysis
 
PDF
Control flow-sensitive optimizations In the Druid Meta-Compiler
 
PDF
Clean Blocks (IWST 2025, Gdansk, Poland)
 
PDF
Encoding for Objects Matters (IWST 2025)
 
PDF
Challenges of Transpiling Smalltalk to JavaScript
 
PDF
Immersive experiences: what Pharo users do!
 
PDF
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
 
PDF
Cavrois - an Organic Window Management (ESUG 2025)
 
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
 
Micromaid: A simple Mermaid-like chart generator for Pharo
 
Directing Generative AI for Pharo Documentation
 
Even Lighter Than Lightweiht: Augmenting Type Inference with Primitive Heuris...
 
Composing and Performing Electronic Music on-the-Fly with Pharo and Coypu
 
Gamifying Agent-Based Models in Cormas: Towards the Playable Architecture for...
 
Analysing Python Machine Learning Notebooks with Moose
 
FASTTypeScript metamodel generation using FAST traits and TreeSitter project
 
Migrating Katalon Studio Tests to Playwright with Model Driven Engineering
 
Package-Aware Approach for Repository-Level Code Completion in Pharo
 
Evaluating Benchmark Quality: a Mutation-Testing- Based Methodology
 
An Analysis of Inline Method Refactoring
 
Identification of unnecessary object allocations using static escape analysis
 
Control flow-sensitive optimizations In the Druid Meta-Compiler
 
Clean Blocks (IWST 2025, Gdansk, Poland)
 
Encoding for Objects Matters (IWST 2025)
 
Challenges of Transpiling Smalltalk to JavaScript
 
Immersive experiences: what Pharo users do!
 
ChatPharo: an Open Architecture for Understanding How to Talk Live to LLMs
 
Cavrois - an Organic Window Management (ESUG 2025)
 

Recently uploaded (20)

PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PPTX
history of c programming in notes for students .pptx
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Design an Analysis of Algorithms II-SECS-1021-03
How to Choose the Right IT Partner for Your Business in Malaysia
Wondershare Filmora 15 Crack With Activation Key [2025
Odoo Companies in India – Driving Business Transformation.pdf
Adobe Illustrator 28.6 Crack My Vision of Vector Design
wealthsignaloriginal-com-DS-text-... (1).pdf
Digital Systems & Binary Numbers (comprehensive )
CHAPTER 2 - PM Management and IT Context
PTS Company Brochure 2025 (1).pdf.......
Softaken Excel to vCard Converter Software.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Operating system designcfffgfgggggggvggggggggg
Understanding Forklifts - TECH EHS Solution
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
history of c programming in notes for students .pptx
L1 - Introduction to python Backend.pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025

Functional Smalltalk

  • 1. Functional Smalltalk Dave Mason Toronto Metropolitan University ©2022 Dave Mason
  • 2. Value I’m going to start with a quote from Kent Beck
  • 3. Value Software creates value 2 ways: What it does today What new things we can make it do tomorrow
  • 4. Value Software creates value 2 ways: What it does today What new things we can make it do tomorrow
  • 5. Value Software creates value 2 ways: What it does today What new things we can make it do tomorrow
  • 6. Value Smalltalk creates value 2 ways: What it does today What new things we can make it do tomorrow
  • 7. Functional Smalltalk Smalltalk already has many functional features extensions by syntax extensions by class
  • 8. Functional Smalltalk Smalltalk already has many functional features extensions by syntax extensions by class
  • 9. Syntax: Functional Programming Smalltalk has always had blocks - needed full closures CompileWithCompose in Pharo-Functional repo leverages class-bounded alternative compiler just syntactic sugar - more succinct all are upward compatible as they are currently syntax errors
  • 10. Syntax: Functional Programming Smalltalk has always had blocks - needed full closures CompileWithCompose in Pharo-Functional repo leverages class-bounded alternative compiler just syntactic sugar - more succinct all are upward compatible as they are currently syntax errors
  • 11. Syntax: Functional Programming Smalltalk has always had blocks - needed full closures CompileWithCompose in Pharo-Functional repo leverages class-bounded alternative compiler just syntactic sugar - more succinct all are upward compatible as they are currently syntax errors
  • 12. Syntax: Functional Programming Smalltalk has always had blocks - needed full closures CompileWithCompose in Pharo-Functional repo leverages class-bounded alternative compiler just syntactic sugar - more succinct all are upward compatible as they are currently syntax errors
  • 13. Syntax: Functional Programming Smalltalk has always had blocks - needed full closures CompileWithCompose in Pharo-Functional repo leverages class-bounded alternative compiler just syntactic sugar - more succinct all are upward compatible as they are currently syntax errors
  • 14. Compose/pipe/parrot operator very convenient to pass result of one expression to another without parentheses particularly convenient in PharoJS for e.g. D3
  • 15. Compose/pipe/parrot operator very convenient to pass result of one expression to another without parentheses particularly convenient in PharoJS for e.g. D3 1 foo 2 " s e l f new foo >>> 42 " 3 ↑ 17 negated 4 :> min: -53 5 :> abs 6 :> < 100 7 :> and: [ 4 > 2 ] 8 :> and: [ 5 < 10 ] 9 :> ifTrue: [ 42 ] ifFalse: [ 99 ]
  • 16. Compose/pipe/parrot operator very convenient to pass result of one expression to another without parentheses particularly convenient in PharoJS for e.g. D3 1 foo 2 " s e l f new foo >>> 42 " 3 ↑ 17 negated 4 :> min: -53 5 :> abs 6 :> < 100 7 :> and: [ 4 > 2 ] 8 :> and: [ 5 < 10 ] 9 :> ifTrue: [ 42 ] ifFalse: [ 99 ]
  • 17. ... Compose/pipe/parrot operator The precedence is the same as cascade, so you can intermix them and could say something like: 1 x := OrderedCollection new 2 add: 42; 3 add: 17; 4 yourself 5 :> collect: #negated 6 :> add: 35; 7 add: 99; 8 yourself 9 :> with: #(1 2 3 4) collect: [:l :r| l+r ] 10 :> max
  • 18. ... Compose/pipe/parrot operator If you don’t want to use the alternate compiler (and get the :> syntax) PharoFunctional also provides a chain method on Object that supports chaining using cascades (unfortunately quite a bit slower because it requires a DNU and perform for each chained message): 1 foo 2 " s e l f new foo >>> 42 " 3 ↑ 17 chain 4 negated 5 ; min: -53 6 ; abs 7 ; < 100 8 ; and: [ 4 > 2 ] 9 ; and: [ 5 < 10 ] 10 ; ifTrue: [ 42 ] ifFalse: [ 99 ]
  • 19. Point-free programming style popular style of functional programming composing functions to build up operations with implicit parameters various “combinators” that recognize patterns in these compositions in Smalltalk this is composing symbols and blocks e.g. 1 isPalindrome := #reverse <| > #= . 2 isPalindrome value: ’madam’
  • 20. Point-free programming style popular style of functional programming composing functions to build up operations with implicit parameters various “combinators” that recognize patterns in these compositions in Smalltalk this is composing symbols and blocks e.g. 1 isPalindrome := #reverse <| > #= . 2 isPalindrome value: ’madam’
  • 21. Point-free programming style popular style of functional programming composing functions to build up operations with implicit parameters various “combinators” that recognize patterns in these compositions in Smalltalk this is composing symbols and blocks e.g. 1 isPalindrome := #reverse <| > #= . 2 isPalindrome value: ’madam’
  • 22. Point-free programming style popular style of functional programming composing functions to build up operations with implicit parameters various “combinators” that recognize patterns in these compositions in Smalltalk this is composing symbols and blocks e.g. 1 isPalindrome := #reverse <| > #= . 2 isPalindrome value: ’madam’
  • 23. Point-free programming style popular style of functional programming composing functions to build up operations with implicit parameters various “combinators” that recognize patterns in these compositions in Smalltalk this is composing symbols and blocks e.g. 1 isPalindrome := #reverse <| > #= . 2 isPalindrome value: ’madam’
  • 24. Expressions as unary or binary messages To use point-free style, it is very convenient to have a more succinct syntax for applying them 1 x (...) 2 x (...) + y 3 x (...): y 4 x (#sort <| > #=) Converts to. 1 ([...] value: x) 2 ([...] value: x) + y 3 ([...] value: x value: y) 4 ((#sort <| > #=) value: x)
  • 25. Blocks as unary or binary messages You can do the same with unary or binary blocks. Because we know the arity of blocks the trailing : isn’t used for block operators 1 x [:w| ...] 2 x [:w:z| ...] y becomes 1 ([:w| ...] value: x) 2 ([:w:z| ...] value: x value: y)
  • 26. Initializing local variables at point of declaration Even in functional languages where mutation is possible, it is rarely used. Instead programming is by a sequence of definitions, which always have a value. I personally very much miss this in Smalltalk. 1 | w x := 42. y = x+5. z a | is legal, but 1 | x := 42. y = x+5. z = 17 | isn’t.
  • 27. Collection literals Arrays have a literal syntax {1 . 2 . 3}, but other collections don’t. This extension recognizes :className immediately after the { and translates, e.g. 1 {:Set 3 . 4 . 5 . 3} 2 {:Dictionary #a->1 . #b->2} 3 {:Set 1 . 2 . 3 . 4 . 5 . 6 . 7} to 1 Set with: 3 with: 4 with: 5 with: 3 2 Dictionary with: #a->1 with: #b->2 3 Set withAll: {1 . 2 . 3 . 4 . 5 . 6 . 7}
  • 28. Destructuring collections There isn’t a convenient way to return multiple values from a method, or even to extract multiple values from a collection. For example: 1 :| a b c | := some-collection destructures the 3 elements of a SequenceableCollection or would extract the value of keys #a #b etc. if it was a Dictionary, with anything else being a runtime error. This is conveniently done by converting that to: 1 ([:temp| 2 a := temp firstNamed: #a. 3 b := temp secondNamed: #b. 4 c := temp thirdNamed: #c. 5 temp] value: some-collection)
  • 29. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 30. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 31. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 32. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 33. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 34. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 35. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 36. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 37. Classes: Functional Programming PharoFunctional adds several new classes and a variety of extension methods to facilitate functional programming. curry: and @@ value:, value:value: and cull, etc. for Symbol map:, map:map: for BlockClosure and Symbol <*> and other combinators for BlockClosure and Symbol nilOr:, emptyOrNilOr: Slice, Pair and Tuple, ZippedCollection zip:, >===< iota many algorithms on collections: rotate:, slide:, product, allEqual, unique, isUnique, groupByRunsEqual:, groupByRunsTrue:
  • 38. Demo
  • 39. Using CompileWithCompose 1 Metacello new 2 baseline: ’PharoFunctional’; 3 repository: ’github://dvmason/Pharo-Functional:ma 4 load: #compiler Then for any class heirarchy, add a trait: 1 RBScannerTest subclass: #ComposeExampleTest 2 uses: ComposeSyntax 3 instanceVariableNames: ’’ 4 classVariableNames: ’’ 5 package: ’CompileWithCompose-Tests’ Or, on the class-side define the following method: 1 compilerClass 2 " Answer a compiler c l a s s a p p r o p r i a t e f o r source 3 ↑ ComposeCompiler You can use this second approach if you want to add it to the entire image (including in playgrounds), by defining this in Object class.
  • 40. Conclusions Smalltalk already has the fundamentals for functional programming some simple syntactic suger can make it a lot more pleasant I would love it if some of these became mainstream (with no backward compatibility issues) in the meantime, anyone can add this to their Pharo the compiler tweaks are not hard for other Smalltalks to implement
  • 41. Conclusions Smalltalk already has the fundamentals for functional programming some simple syntactic suger can make it a lot more pleasant I would love it if some of these became mainstream (with no backward compatibility issues) in the meantime, anyone can add this to their Pharo the compiler tweaks are not hard for other Smalltalks to implement
  • 42. Conclusions Smalltalk already has the fundamentals for functional programming some simple syntactic suger can make it a lot more pleasant I would love it if some of these became mainstream (with no backward compatibility issues) in the meantime, anyone can add this to their Pharo the compiler tweaks are not hard for other Smalltalks to implement
  • 43. Conclusions Smalltalk already has the fundamentals for functional programming some simple syntactic suger can make it a lot more pleasant I would love it if some of these became mainstream (with no backward compatibility issues) in the meantime, anyone can add this to their Pharo the compiler tweaks are not hard for other Smalltalks to implement
  • 44. Conclusions Smalltalk already has the fundamentals for functional programming some simple syntactic suger can make it a lot more pleasant I would love it if some of these became mainstream (with no backward compatibility issues) in the meantime, anyone can add this to their Pharo the compiler tweaks are not hard for other Smalltalks to implement