The Ragel 6.10 manual has many illustrations of the FSM it generates. Some of which show a state DEF.
As best I can tell this is never defined/discussed.
What is the DEF state?
What are its implications? e.g. if it shows up in your FSM abc should be done
Thanks in advance
Answer to Q1:
DEF represents the default transition, which is taken if no other transition can be taken.
Answer to Q2:
This depends on what you are using Ragel for.
Defining FSM using regular languages:
Do you want move from State A to State B on any character?
Defining FSM using state charts:
Do you want to move from State A to State B on any event? Do you have a notion of a 'default' transition?.
This issue be most clearly understood by working though the example in Section 6.4.5 of the manual (version 6.10), where parsing and state charts are both used.
This can sometimes arise when you use explicitly any as a state.
Example:
%%{
machine def_eg;
action to_action_1 {}
action to_action_2 {}
action from_action_1 {}
eg = (
start: (
any -> s1
),
s1: (
any -> s2
)>to(to_action_1) >from(from_action_1),
s2: (
any -> final
)>to(to_action_2)
);
main := ( eg ) ;
}%%
%% write data
And the graphviz (ragel -Vp -o def_eg.dot def_eg.rl):
Now, with the expressions changed from any character to a single character. And using these single characters to represent states.
%%{
machine def_eg;
event_1='1';
event_2='2';
event_3='3';
action to_action_1 {}
action to_action_2 {}
action from_action_1 {}
eg = (
start: (
event_1 -> s1
),
s1: (
event_2 -> s2
)>to(to_action_1) >from(from_action_1),
s2: (
event_3 -> final
)>to(to_action_2)
);
main := ( eg ) ;
}%%
%% write data
Is illustrated as:
Related
I just started programming functionally. My current tiny project to start would be a basic pokemon battle.
Code first, explanation follows.
let choosePokemon () =
let mutable pokemon = DemoData.schiggy
let msg = Console.ReadLine()
match msg with
| "Schiggy" -> pokemon <- DemoData.schiggy
| "Pikachu" -> pokemon <- DemoData.pikachu
| "Kleinstein" -> pokemon <- DemoData.kleinstein
| "Karpador" -> pokemon <- DemoData.karpador
pokemon
I am currently asking people to enter the name of a Pokemon and if it matches a predefined set (Schiggy, Pikachu, Kleinstein or Karpador) it gives them the respective Pokemon. Alternatively it gives them the default Pokemon.
I am currently creating it before matching it with "let mutable pokemon = DemoData.schiggy". I don't want that. I just want to assign it based on its name.
If I could go without that line I'd avoid making it mutable, which is something I don't want anyways.
Additional question further down the line: When Pokemon attack each other their hp will decrease.
How can I avoid using a mutable int when facing a changing int value?
Thanks in advance :)
Just return the result from the match - there's no need to declare a variable:
let choosePokemon () =
let msg = Console.ReadLine()
match msg with
| "Schiggy" -> DemoData.schiggy
| "Pikachu" -> DemoData.pikachu
| "Kleinstein" -> DemoData.kleinstein
| "Karpador" -> DemoData.karpador
The function is still impure, though, since it performs I/O (Console.ReadLine)...
It's also partial, since it'll crash on any other input than the four strings being matched. Even misspellings and case mistakes are going to throw an exception.
A more robust pure function would be something like this:
let choosePokemon (input : string) =
match input.Trim().ToUpperInvariant () with
| "PIKACHU" -> DemoData.pikachu
| "KLEINSTEIN" -> DemoData.kleinstein
| "KARPADOR" -> DemoData.karpador
| _ -> DemoData.schiggy
Contrary to the OP that performs I/O, this version is a pure function, since there's no non-deterministic behaviour. It's also total, since it returns schiggy as a default value.
To get the behaviour where you ask the user to input a value, compose the impure Console.ReadLine action with the pure choosePokemon function:
Console.ReadLine >> choosePokemon
I am stuck with a functionality that i have already done in python long time ago.
I draw a gantt chart in a specific way that i can't reproduce with elm.
here is my code :
https://ellie-app.com/8sYLsxTZHk5a1
The problem is in the "calcTaskPosition" function where i try to set the row of the task.
calcTaskPosition : Int -> Task -> List(Task)
calcTaskPosition row task =
let
precs = List.concatMap (calcTaskPosition (row+1)) (taskPrecs task)
in
{ task | col = (Maybe.withDefault -1 <|
List.maximum <|
List.map (\t -> t.col) precs) + 1
--, row = row
}
:: precs
In my example, tasks lines are set by the initTask function.
I wish to get the same task order whithout having to set explicit line position in the initTask function.
The first clue is when you look at svg you will notice that your "task1" is actually rendered twice. This is easier to see if you uncomment the line --, row = row in the snippet you posted.
In elm (and other functional languages) your tasks will not be manipulated in-place, but instead your tasks will be copied when you mutate them. So it is not really useful to keep col and row values in the model (for now).
Also, working with task ids makes more sense than directly linking objects.
With this in mind, I would create two different task records: One for keeping it in the model (Task in my example) and one for rendering it (I called it DrawableTask).
And then you need a transformation function like
toDrawableListOfTasks : List Task -> List DrawableTask
that will be called in the view.
The transformation function essentially uses your tasksNotInTaskPrecs where you select all tasks that can be immediately drawn (because their precs list is empty). I generalized it and called it allDependenciesMet instead and use it on every iteration to select the tasks that can be drawn.
All tasks that can be drawn will be added to a temporary list (in my case a dictionary for fast look-up of already entered tasks) and then the next iteration starts with all tasks that were not yet drawn.
When no tasks are left, you can return the list and the rendering pass will traverse the list once again.
order : Temp -> List Task -> List DrawableTask
order temp todo =
case List.partition (allDependenciesMet temp) todo of
( [], [] ) ->
-- We are done and can return the list
Dict.values temp
|> List.sortBy .row
( [], _ ) ->
Debug.todo "An invalid list of tasks was passed"
( drawableTasks, nextTodo ) ->
let
nextTemp =
List.indexedMap (toDrawable temp) drawableTasks
|> List.map (\t -> ( t.id, t ))
|> Dict.fromList
|> Dict.union temp
in
order nextTemp nextTodo
I'm not sure if this is understandable, but you should be able to follow https://ellie-app.com/8tdzrgLfBfya1
I created a simple code
package main
import (
"fmt"
)
func main() {
a := 5
b := &a
Test(b)
fmt.Println(a)
fmt.Println(*b)
}
func Test(result interface{}){
switch r := result.(type) {
case *int:
*r = 10
}
}
You can run it here
In Test method inside switch statement I create new variable that is a type of my parameter.
Why does my variable 'b' update after update of this pointer. Why does this new variable points to the old one?
The result of program execution is
10
10
But expected
5
5
UPDATE
I'd like to precise the question. I did not assign my pointer to 'b' to variable 'r' in Test.
I expect that
r := result.(type)
gives me the type of the result. But why if I change value of a pointer of a new variable result is changed too
UPDATE 2
As suggested I checked again a specification and didn't found an answer. In the next construction
switch r := result.(type) {
case *int:
*r = 10
}
What does result.(type) return exactly?
A type switch compares types rather than values. It is otherwise similar > to an expression switch. It is marked by a special switch expression that > has the form of a type assertion using the reserved word type rather than > an actual type:
switch x.(type) {
// cases
}
See information on type assertions here and here.
There is a good description of pointers in go here.
In your code &a means the address of a and b returns a pointer to an int (*int).
In the Test function you are saying store the value 10 in the memory location pointed to by r.
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 seen in my SML manual the following function, which computes how many coins of a particular kind are needed for a particular change.
For example change [5,2] 16 =[5,5,2,2,2] because with two 5-coins and three 2-coins one gets 16.
the following code is a backtracking approach:
exception Change;
fun change _ 0 = nil|
change nil _ = raise Change|
change (coin::coins)=
if coin>amt then change coins amt
else (coin:: change (coin::coins) (amt-coin))
handle Change=> change coins amt;
It works, but I don't understand how exactly.
I know what backtracking is, I just don't understand this particular function.
What I understood so far: If amt is 0, it means our change is computed, and there is nothing to be cons'd onto the final list.
If there are no more coins in our 'coin-list', we need to go back one step.
This is where I get lost: how exactly does raising an exception helps us go back?
as I see it, the handler tries to make a call to the change function, but shouldn't the "coins" parameter be nil? therefore entering an infinite loop? why does it "go back"?
The last clause is pretty obvious to me: if the coin-value is greater than the amount left to change, we use the remaining coins to build the change. If it is smaller than the amount left, we cons it onto the result list.
This is best seen by writing out how evaluation proceeds for a simple example. In each step, I just replace a call to change by the respective right-hand side (I added extra parentheses for extra clarity):
change [3, 2] 4
= if 3 > 4 then ... else ((3 :: change [3, 2] (4 - 3)) handle Change => change [2] 4)
= (3 :: change [3, 2] 1) handle Change => change [2] 4
= (3 :: (if 3 > 1 then change [2] 1 else ...)) handle Change => change [2] 4
= (3 :: change [2] 1) handle Change => change [2] 4
= (3 :: (if 2 > 1 then change [] 1 else ...)) handle Change => change [2] 4
= (3 :: (raise Change)) handle Change => change [2] 4
At this point an exception has been raised. It bubbles up to the current handler so that evaluation proceeds as follows:
= change [2] 4
= if 2 > 4 then ... else ((2 :: change [2] (4 - 2)) handle Change => change [] 4)
= (2 :: change [2] 2) handle Change => change [] 4
= (2 :: (if 2 > 2 then ... else ((2 :: change [2] (2 - 2)) handle Change => change [] 2)) handle Change => change [] 4
= (2 :: ((2 :: change [2] 0) handle Change => change [] 2)) handle Change => change [] 4
= (2 :: ((2 :: []) handle Change => change [] 2)) handle Change => change [] 4
= (2 :: (2 :: [])) handle Change => change [] 4
= 2 :: 2 :: []
No more failures up to here, so we terminate successfully.
In short, every handler is a backtracking point. At each failure (i.e., raise) you proceed at the innermost handler, which is the last backtracking point. Each handler itself is set up such that it contains the respective call to try instead.
You can rewrite this use of exceptions into using the 'a option type instead. The original function:
exception Change;
fun change _ 0 = []
| change [] _ = raise Change
| change (coin::coins) amt =
if coin > amt
then change coins amt
else coin :: change (coin::coins) (amt-coin)
handle Change => change coins amt;
In the modified function below, instead of the exception bubbling up, it becomes a NONE. One thing that becomes slightly more apparent here is that coin only occurs in one of the two cases (where in the code above it always occurs but is reverted in case of backtracking).
fun change' _ 0 = SOME []
| change' [] _ = NONE
| change' (coin::coins) amt =
if coin > amt
then change' coins amt
else case change' (coin::coins) (amt-coin) of
SOME result => SOME (coin :: result)
| NONE => change' coins amt
Another way to demonstrate what happens is by drawing a call tree. This does not gather the result as Andreas Rossberg's evaluation by hand, but it does show that only the times change is taking an else-branch is there a possibility to backtrack, and if a backtrack occurs (i.e. NONE is returned or an exception is thrown), don't include coin in the result.
(original call ->) change [2,5] 7
\ (else)
`-change [2,5] 5
/ \ (else)
___________________/ `-change [2,5] 3
/ / \ (else)
/ / `-change [2,5] 1
`-change [5] 5 / \ (then)
\ (else) / `-change [5] 1
`-change [] 0 / \ (then)
\ / `-change [] 1
`-SOME [] `-change [5] 3 \ (base)
\ (then) `-NONE
`-change [] 3
\
`-NONE
Source: https://www.cs.cmu.edu/~rwh/introsml/core/exceptions.htm
The expression exp handle match is an exception handler. It is
evaluated by attempting to evaluate exp. If it returns a value, then
that is the value of the entire expression; the handler plays no role
in this case. If, however, exp raises an exception exn, then the
exception value is matched against the clauses of the match (exactly
as in the application of a clausal function to an argument) to
determine how to proceed. If the pattern of a clause matches the
exception exn, then evaluation resumes with the expression part of
that clause. If no pattern matches, the exception exn is re-raised so
that outer exception handlers may dispatch on it. If no handler
handles the exception, then the uncaught exception is signaled as the
final result of evaluation. That is, computation is aborted with the
uncaught exception exn.
In more operational terms, evaluation of exp handle match proceeds by
installing an exception handler determined by match, then evaluating
exp. The previous binding of the exception handler is preserved so
that it may be restored once the given handler is no longer needed.
Raising an exception consists of passing a value of type exn to the
current exception handler. Passing an exception to a handler
de-installs that handler, and re-installs the previously active
handler. This ensures that if the handler itself raises an exception,
or fails to handle the given exception, then the exception is
propagated to the handler active prior to evaluation of the handle
expression. If the expression does not raise an exception, the
previous handler is restored as part of completing the evaluation of
the handle expression.