I may not have the right vocabulary for this question, but I'm looking to understand a fundamental concept of functional programming. Thank you for reading!
If you write a purely functional program that interacts with multiple consumers, how do you model shared information? Using the example of a bank account...
With mutable variables, you can do something like this:
class BankAccount {
private var bal: Int = 0
def balance: Int = bal
def deposit(amount: Int) {
bal += amount
}
def withdraw(amount: Int) {
bal += amount
}
}
So if the balance was $0 at t0 and Bob deposits 5 at t1, then Mary checks the balance at t2, she sees 5, that is she sees the effect of Bob's action.
How would you implement this with functional programming, where variable are supposed to be immutable? I can understand that with a single consumer, Bob, you can return a new instance of BankAccount with a balance of 5. But with a second consumer, Mary, how would she access this new BankAccount?
Conceptually, one can think about balance not as a state that changes over time, but rather there is an immutable balance_t0 = 0 and an immutable balance_t1 = 5. But to do this, you would still need some way to name the balance at each point in time in your programming language...
Related
I understand that functional architecture is encouraged in F#, but I'm hitting a performance wall that doesn't exist with class types.
I have a state type with a bunch of fields in it and it is passed around a series of functions through the code pipeline.
At every state, when some transformation occurs, a new object is created.
Some example is this:
match ChefHelpers.evaluateOpening t brain with
| Some openOrder ->
info $"open order received: {openOrder.Side}"
match! ExchangeBus.submitOneOrderRetryAsync brain.Exchange openOrder with
| Ok _->
{brain.CookOrder.Instrument.PriceToString openOrder.Price} / sl.{stopLossOrder.Side.Letter} at {brain.CookOrder.Instrument.PriceToString stopLossOrder.Price}"
let m = $"{t.Timestamp.Format}: send open order {openOrder.Side}, last price was {brain.CookOrder.Instrument.PriceToString brain.Analysis.LastPrice}"
return Message m, ({ brain.WithStatus (Cooking MonitorForClose) with OpenOrder = Some openOrder })
| Error e ->
let m = $"{t.Timestamp}: couldn't open position:\n{e.Describe()}"
return! ChefHelpers.cancelAllOrdersAsync brain (ChefError m) (ExchangeError (Other (e.Describe())))
| None ->
return NoMessage, brain
Where the object 'brain' that holds all the states will get passed around, updated, etc
And this works very well when run live since everything may get executed a 2-3 times per second at most.
When I want to run the same code on static data to check behavior, etc, this is a different story because I'm running it millions of times while I'm waiting for it to finish.
All this code is dealing with small lists, doing basic comparisons, arithmetic, etc so the the cost of rebuilding the main object sticks out and becomes painfully apparent.
I tried to rebuild some of that logic as an object type where the state is a bunch of mutable variables and the performance difference is dramatic.
I have a lot of code like this:
type A = { }
let a : A = ...
let a = doSomething1 a
let a = doSomething2 a
let a =
match x with
| true -> doSomething3 a
| false -> a
etc
I'd say the whole tool architecture is built with code that looks like that.
and there is a lot of these:
let a = { a with X = 3 }
but there is no concurrency in the pipeline and it is very linear, so in the case of the last line, if I had a way to tell the compiler: it's the same object, it is not used anywhere else, edit it in place, then the performance would be a lot better.
What could be strategies I could use to keep the code readable, but minimize that issue?
Is the problem the actual data copying? the main object has 18 fields, so I can't imagine it being larger than 200 bytes, allocating space for it? or does it create a lot of garbage collection?
It's not something straightforward to profile since it's a cost that's everywhere and inside dotnet.
Any feedback / ideas would be great, especially "you're doing it wrong, do X instead" :)
From a design perspective, 18 fields is actually a fairly large record, in my opinion. Perhaps you could factor that into sub-records, so you're not constantly re-allocating the entire thing? So instead of this:
type A =
{
X : int
Field1 : int
Field2 : int
...
Field18 : int
}
You could have this instead:
type Sub1 =
{
Field1 : int
...
Field9 : int
}
type Sub2 =
{
Field10 : int
...
Field18 : int
}
type A =
{
X : int
Sub1 : Sub1
Sub2 : Sub2
}
Then the performance cost of let a = { a with X = 3 } would presumably be less.
Bonus idea: You might also want to emulate the cool Haskell kids, and look into lenses, which are designed specifically for reading and updating parts of immutable data.
I'm new to PureScript. I was searching for sealed classes in Purescript to get an idea of how one would implement this, but I don't think I have the necessary PS jargon yet.
What is the canonical way in PureScript to have a bunch of records that extend a "base" record, but then have one sum type representing a "sealed" collection of those.
Something like in Kotlin,
sealed class Glazing(val name: String, val area: Int) {
class Window(val name: String, val area: Int, val frameMaterial: String): BaseGlazing(name, area)
class Door(val name: String, val area: Int, val isPreHung: Boolean): BaseGlazing(name, area)
}
in TypeScript, you'd probably do something like
interface BaseGlazing { ... }
interface Door extends BaseGlazing { ... }
interface Window extends BaseGlazing { ... }
type Glazing = Door | Window
and then you'd either take `A extends BaseGlazing` or `Glazing` (and use type guards) to do either of those two above functions.
Essentially I want a base class (that is technically abstract), things that extend it, and then a sum type/discriminated union of the extensions so that way I can both write, say, changeName:: Glazing -> Glazing (premised on the base class having a name prop) but also do something like calculateTotalLightPenetration :: Array Glazing -> Number (premised on the discriminated union being one of Door or Window since light penetration will be a different formula for doors vs windows)
The idea of "inheritance" (aka "is-a" relationship) is technically possible to model in PureScript, but it's hard and awkward. And there is a good reason for it: inheritance is almost never (and I am tempted to say "never, period") the most convenient, efficient, or reliable way of modeling the domain. Even OOP apologists tend to recommend aggregation over inheritance these days.
One useful thing to observe is that you don't actually need inheritance. What you need is to solve some specific problem in your domain, and inheritance is just a solution that you naturally reach for, which is probably informed by your past experience.
And this leads us to an insight: the particular way to model whatever it is you're modeling would depend on what the actual problem is. Chances are, PureScript has a different mechanism for modeling that.
But if I base my thinking on the specifics you gave in your question (i.e. the changeName and calculateTotalLightPenetration functions), I would model it via aggregation: the "glazing" would be the surrounding type, and it would have, as one of its parts, the specific kind of glazing. This would look something like this:
type Glazing = { name :: String, area :: Int, kind :: GlazingKind }
data GlazingKind = Window { frameMaterial :: String } | Door { isPreHung :: Boolean }
changeName :: Glazing -> Glazing
changeName g = g { name = "new name" }
calculateTotalLightPenetration :: Array Glazing -> Number
calculateTotalLightPenetration gs = sum $ individualPenetration <$> gs
where
individualPenetration g = case g.kind of
Door _ -> 0.3
Window _ -> 0.5
I've a buffer that is actually ArrayList<Object>.
Happens async:
This buffer list changes very frequently - I mean 15-50 times in single second and the idea is that whenever there's an update, I remove first element by position buffer.removeAt(0) and add new value in the end by buffer.add(new).
At some point I call a function that goes and do calculation with buffer list. What I do is I go through the list - element by element. At some point I run into NPE as the the element has been removed async.
How to solve this NPE? I was thinking of making deep copy, but making deep copy would mean to go through the buffer list and do some data allocation, which basically means that while I do deep copy I can still run into NPE.
How problems like these are solved?
How to solve NPE?
What would be more optimized way as this is gonna consume a lot of memory?
Code:
private fun observeFrequentData() {
frequentData.observe(owner, Observer { data ->
if (accelerationData == null) return#Observer
GlobalScope.launch {
val a = data[0].toDouble()
val b = data[1].toDouble()
val c = a + b
val timestamp = System.currentTimeMillis()
val customObj = CustomObj(c, timestamp)
if (buffer.size >= 5000) {
buffer.removeAt(0)
}
buffer.add(acceleration)
}
})
}
fun getBuffer() {
val mappedData = buffer.map { it.smth } // NPE, it == null
}
If you are doing lots of removing from 0, and insert at the end. Then ArrayList is probably not the container to use.
you can consider using a LinkedList .
buffer.removeFirst();
and
buffer.add(acceleration);
also note the following comments regarding synchronization.
Note that this implementation is not synchronized. If multiple threads
access a linked list concurrently, and at least one of the threads
modifies the list structurally, it must be synchronized externally. (A
structural modification is any operation that adds or deletes one or
more elements; merely setting the value of an element is not a
structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list. If
no such object exists, the list should be "wrapped" using the
Collections.synchronizedList method. This is best done at creation
time, to prevent accidental unsynchronized access to the list:
List list = Collections.synchronizedList(new LinkedList(...));
Using the synchronized keyword on your piece of code as #patrickf suggested.
To take care of performance, instead of making the method call itself synchronized, you can just write the 3 "buffer" related lines of code (size, removeAt and add) in a synchronized block.
Something like;
.
.
.
synchronized {
if (buffer.size >= 5000) {
buffer.removeAt(0)
}
buffer.add(acceleration)
}
}
})
Hope this helps!
I'm currently writing an Android music player application using Scala. I chose Scala for its functional programming capabilities and I want to make the code the most FP compliant possible.
As FP implies immutability, the code should not carry any state and variables should be immutable. But I'm facing some complicate use cases I don't know how to resolve in a pure functional programming way.
The first one is the playlist case. The music player is reading a song in the middle of a playlist. This can be represented with a list of songs and a cursor that indicates the current played song. But when that song ends, then the player has to play the next one, hence, change the value of the cursor.
The same problem happens with the playlist itself: the user must be able to change (add or suppress songs) the playlist. If the playlist itself is immutable, any time the user adds or suppress a song, a new playlist is produced. But that playlist must be affected to a variable that must then be mutable.
Everywhere I look in this application, I see states — is the player paused or not? What is the current song, the current playlist? What is the current state of the settings? Etc. — and I don't know how to solve this in a pure functional programming way, i.e. with immutable variables.
As these use cases seem pretty standard, I suppose there are design patterns to solve them (like monads) but I don't know where to look.
I wrote some libraries that tried to address this, the result was fairly ugly, IMO.
Basically, turned Activity, Fragment, etc. into pure functions that accepted State and returned State.
This in conjunction with IO monads made the interface somewhat pure. An example of this follows (the source to PureActivity can be found at https://github.com/pfn/iota-pure), the 'state' in this case is 'Option[Process]' with Process being present when logcat is running and empty when it is not. No vars:
class LogcatActivity extends AppCompatActivity with PureActivity[Option[Process]] {
val LOG_LINE = """^([A-Z])/(.+?)\( *(\d+)\): (.*?)$""".r
val buffersize = 1024
lazy val toolbar = newToolbar
lazy val recycler = {
val r = new RecyclerView(this)
r.setLayoutManager(new LinearLayoutManager(this))
r.setAdapter(Adapter)
r
}
lazy val layout = l[LinearLayout](
toolbar.! >>= lp(MATCH_PARENT, WRAP_CONTENT),
recycler.! >>= lp(MATCH_PARENT, 0, 1)
) >>= vertical
override def initialState(b: Option[Bundle]) = None
override def applyState[T](s: ActivityState[T]) = s match {
case OnPreCreate(_) => s(IO(
setTheme(if (Settings.get(Settings.DAYNIGHT_MODE)) R.style.SetupTheme_Light else R.style.SetupTheme_Dark)
))
case OnCreate(_) => s(IO {
toolbar.setTitle("Logcat")
toolbar.setNavigationIcon(resolveAttr(R.attr.qicrCloseIcon, _.resourceId))
toolbar.navigationOnClick0(finish())
setContentView(layout.perform())
})
case OnStart(_) => s.applyState(IO {
var buffering = true
val logcat = "logcat" :: "-v" :: "brief" :: Nil
val lineLogger = new ProcessLogger {
override def out(s: => String) = addLine(s)
override def buffer[X](f: => X) = f
override def err(s: => String) = addLine(s)
def addLine(line: String) = line match {
case LOG_LINE(level, tag, pid, msg) =>
if (tag != "ResourceType") UiBus.run {
val c = Adapter.getItemCount // store in case at max items already
Adapter.buffer += LogEntry(tag, level, msg)
Adapter.notifyItemInserted(math.min(buffersize, c + 1))
if (!buffering)
recycler.smoothScrollToPosition(Adapter.getItemCount)
}
case _ =>
}
}
Future {
Thread.sleep(500)
buffering = false
} onSuccessMain { case _ =>
recycler.scrollToPosition(Adapter.getItemCount - 1)
}
logcat.run(lineLogger).?
})
case OnStop(proc) => s.applyState(IO {
proc.foreach(_.destroy())
None
})
case x => defaultApplyState(x)
}
case class LogEntry(tag: String, level: String, msg: String)
case class LogcatHolder(view: TextView) extends RecyclerView.ViewHolder(view) {
def bind(e: LogEntry): Unit = view.setText(" %1 %2: %3" formatSpans (
textColor(MessageAdapter.nickColor(e.level), e.level),
textColor(MessageAdapter.nickColor(e.tag), e.tag), e.msg))
}
object Adapter extends RecyclerView.Adapter[LogcatHolder] {
val buffer = RingBuffer[LogEntry](buffersize)
override def getItemCount = buffer.size
override def onBindViewHolder(vh: LogcatHolder, i: Int) = vh.bind(buffer(i))
override def onCreateViewHolder(viewGroup: ViewGroup, i: Int) = {
val tv = new TextView(LogcatActivity.this)
tv.setTypeface(Typeface.MONOSPACE)
LogcatHolder(tv)
}
}
}
You are talking about the UI. It is stateful in its essence. You cannot and must not work with it without states. There is only one correct way: to divide the code without states from the code with states.
The best concept for that is the FRP - Functional reactive programming. It separates functional parts and immutable boxes with mutable stateful content and connects them by events.
Be careful, many so-named reactive programming technologies on the net are not such really and only declare being reactive. For example, java RX is absolute invalid and lacks two very important features. (hiding listeners and simultaneousity support)
There is a very good book on the subject. It can be found on the net in some actions, too. The authors give opensource base library and swift FRP support library that could be used as a pattern for creation of your own FRP classes for your need.
I have been trying to figure this for over 3 days now. It is part of my fortnightly assignment for my uni. However, I have hit a road block. Any help will be must appreciated.
Specifics of the assignment, I have figured out so far:
I must use an Item class that defines (get and set) the weight and
value of the stuff
Table arrayList holds the value and weight of
item array stuffList
Check if the maximum value stuff (Greedy) fits
inside the bag's capacity and add the index of this stuff from the
table arrayList in the bag arrayList
Return bag arrayList.
The method I have written so far (Doesn't seem to be working):
Public static ArrayList <Integer> greedySelection (Item[] stuffList, int Capacity)
{
ArrayList<Integer> bag = new ArrayList<Integer>();
ArrayList<Integer> Table = new ArrayList<Integer>();
for(int i = 0; i < Table.size(); i++){
if(Table.get(i) < Capacity){
bag.add(i);
Table.remove(i);
}
}
return bag;
}
Your code has several problems. You haven't focused on the basic tenet of a recursive algorithm:
Check to see whether you've "hit bottom".
If so, return the simple result.
If not, then do one trivial operation and recur on the remaining task.
For this routine, you need to figure out
When you've "hit bottom": when you can't add anything else.
What is the simple result at this point? Simply return the existing bag?
To recur, you add the most valuable item (greed) you can fit into the bag and call yourself with the new state of affairs. What is that state of affairs? At the least, you need to adjust the item list, the bag contents, and the remaining capacity.
Note that your initial state has to be set in the calling program and passed into the routine.
Does this get you moving?