go pass dynamically created function as parameter - function

Ok. I have some trouble understanding what exactly is going on here with "MyPrinter"
Let me go step by step (please correct me if got something wrong)
1. The "Salute" structure is created
2. Call to "Greet" function
2.a Call to "CreatePrinterFunction" with the strgin "!!!". This function returns a "MyPrinter" (witch is a function that takes in a string and returns nothing)
3. the variables "message" and "defaultMessage" are set with the strings
Now here's the problem, I don't understand what exactly are those do("str") doing
package main
import "fmt"
type Salute struct {
name string
greeting string
}
type MyPrinter func (s string) ()
func Greet(salute Salute, do MyPrinter) {
message, defaultMessage := CreateMessage(salute.name, salute.greeting, "noName")
do(message)
do(defaultMessage)
}
func Print(s string) {
fmt.Print(s)
}
func PrintLine(s string) {
fmt.Println(s)
}
func CreatePrinterFunction(custom string) MyPrinter {
return func (s string) {
fmt.Println(s + custom)
}
}
func CreateMessage(name string, greeting ...string) (message string, defaultMessage string) {
message = name + " " + greeting[0]
defaultMessage = "hey " + name
return
}
func main() {
var s = Salute{"Joe", "hello"}
// Greet(s, PrintLine)
Greet(s, CreatePrinterFunction("!!!"))
}

CreatePrinterFunction returns a function literal:
return func (s string) {
fmt.Println(s + custom)
}
That function literal implements the MyPrinter interface, which is an interface implemented by any function that takes a string argument and returns nothing:
type MyPrinter func(s string)
(note that the MyPrinter definition in the provided snippet includes an extra () at the end which does nothing)
Then, that function created which implements the MyPrinter interface is passed as the do parameter of the Greet function:
func Greet(salute Salute, do MyPrinter) {
When code inside Greet runs do(message), the created function literal is called, which in its turn runs the equivalent of fmt.Println(message + custom).
It's a pretty convoluted way to do something simple. :-)

Related

Why does the function execution order seem reversed when I append function calls?

I was reading this question: Decorator functions in Go and am wondering why the execution order of the example in the accepted answer seems reversed to me.
I have broken it down to the following minimal example and am wondering if the effect is due to function chaining.
// Interesting Part
some_string := "Some_String"
var fn3 StringManipulator = ident
fn3 = AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", fn3)))
fmt.Println(fn3(some_string))
// Prints "DECORATED some_string golang"
// Function Definitions
func ToLower(m StringManipulator) StringManipulator {
return func(s string) string {
lower := strings.ToLower(s)
return m(lower)
}
}
func AppendDecorator(x string, m StringManipulator) StringManipulator {
return func(s string) string {
return m(s + x)
}
}
func PrependDecorator(x string, m StringManipulator) StringManipulator {
return func(s string) string {
return m(x + s)
}
}
As mentioned in the code this yields "DECORATED some_string golang" indicating that the functions were executed from left to right, whereas normal functions evaluate from innermost to outermost, i.e. right to left. [This reminds me of postmultiplication of transformation matrices - there the order is also "reversed", i.e. M_1 * M_2 * M_3] Is this due to function chaining or what is the reason? Could somebody help me understand how this executes in detail?
Thank you in advance.
I rewrote your example to illustrate.
The nested function calls execute from inside to outside. Each function call returns a function. Eventually the variable m is assigned the result of AppendDecorator which is itself a function composed of all the decorators that looks something like this:
m := func(s string) string {
return ("DECORATED " + strings.ToLower(s + " GOLANG"))
}
When we execute m(s) (inside fmt.Println(m(s)) we are executing the function returned by AppendDecorator. This function calls m(s + x) where m is the function returned by ToLower. When this function executes it calls m(lower) where m is the function returned by PrependDecorator. When this function executes it calls m(x + s) where m is the Identity function that we passed in.
package main
import (
"fmt"
"strings"
)
// StringManipulator manipulate a string
type StringManipulator func(str string) string
// Identity a string manipulator that leaves the string unchanged
func Identity(s string) string {
fmt.Println("Executing Identity manipulator")
return s
}
// ToLower a lower case string manipulator
func ToLower(m StringManipulator) StringManipulator {
fmt.Println("Returning ToLower manipulator")
return func(s string) string {
fmt.Println("Executing ToLower manipulator")
lower := strings.ToLower(s)
return m(lower)
}
}
// AppendDecorator append a string manipulator
func AppendDecorator(x string, m StringManipulator) StringManipulator {
fmt.Println("Returning Append manipulator")
return func(s string) string {
fmt.Println("Executing Append manipulator")
return m(s + x)
}
}
// PrependDecorator prepend a string manipulator
func PrependDecorator(x string, m StringManipulator) StringManipulator {
fmt.Println("Returning Prepend manipulator")
return func(s string) string {
fmt.Println("Executing Prepend manipulator")
return m(x + s)
}
}
func main() {
s := "Some_String"
m := AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", Identity)))
fmt.Println(m(s))
}
The output from m := AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", Identity))) is:
Returning Prepend manipulator
Returning ToLower manipulator
Returning Append manipulator
and the output from fmt.Println(m(s)) is:
Executing Append manipulator
Executing ToLower manipulator
Executing Prepend manipulator
Executing Identity manipulator
DECORATED some_string golang

none return value function in Golang

While I was reading "the little go" book, I found that it suggests to write a function without any return value. So I proceed to test that function but the program won't compile and give me this "... used as value"error. Anyone knows what is going on here?
package main
import (
"fmt"
)
func log(message string) {
fmt.Println(message)
}
func main() {
msg := log("just a message")
fmt.Println(msg)
}
I know that this function is trivial (maybe the question is stupid also). But I am just curious to know if this type of function legal in Go?
The function here you have used
func log(message string){
fmt.Println(message)
}
Actually returns nothing.
But you are assigning it to a variable is incorrect. Since function returns nothing.
msg := log("just a message")
and that's why the error
.. used as value
You can call it directly.
func main() {
log("just a message")
}
Check out on go playground
A function that returns nothing is perfectly valid:
func log(message string) {
// .. do stuff
}
But treating it as though it returns something is invalid:
msg := log("foo") // what do you expect to be assigned to msg? log() returns nothing!
Your log() function does not return anything so you can’t assign it result to a variable (msg := ...)
import(
"fmt"
)
func log(message string){
fmt.Println(message)
}
func main(){
log("just a message")
}

Accessing function defined within function in swift

Say I have a class NamedShape defined like this:
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
func containerFunc() -> Void{
println("strange world")
func subFunc() -> String {
return "sub function returns string"
}
println(subFunc())
}
}
I can initialize it like this:
let someNamedShape = NamedShape(name:"polynomial")
And invoke some method like this:
someNamedShape.containerFunc()
Now how can I invoke method subFunc within containerFunc on its object?
Compiler complains while trying this:
someNamedShape.containerFunc().subFunc()
It looks like it's not possible, unless you return the inner function from its containing function. Here's what the documentation says
Nested functions are hidden from the outside world by default, but can still be called and used by their enclosing function. An enclosing function can also return one of its nested functions to allow the nested function to be used in another scope.
This is how your code should look like in order to be able to call the subfunc
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
func containerFunc() -> (() -> String) {
println("strange world")
func subFunc() -> String {
return "sub function returns string"
}
println(subFunc())
return subFunc
}
}
let someNamedShape = NamedShape(name:"polynomial")
let subfunc = someNamedShape.containerFunc()
subfunc()

Passing inline function definition as input parameter to a function

Say, I have a function which accepts a function as one of the input parameters:
// modify passed string
func modifyString(paramString: String, modificationFunction: String -> String) -> String {
return modificationFunction(paramString)
}
Now I can define a function like this:
func addLearningSuffix(inputString: String) -> String {
var returnString = inputString + " is learning swift"
return returnString
}
And use it like this:
// adds suffix - is learning swift
modifyString("Miraaj", addLearningSuffix) // returns "Miraaj is learning swift"
In above case I just passed function name - addLearningSuffix as input parameter to the function - modifyString, but what if I want to define function in the same line while passing it as input parameter.
I know that functions are special case of closures, so I can pass inline closure like this:
// adds prefix - Miraaj
modifyString("is learning swift",{
(inputString: String) -> String in
let result = "Miraaj " + inputString
return result // returns "Miraaj is learning swift"
})
or like this:
modifyString("is learning swift"){
(inputString: String) -> String in
let result = "Miraaj " + inputString
return result
}
But why I can't pass inline function definition like this:
modifyString(" is learning swift", func addSomeOtherPrefix(inputString: String) -> String{
return "Miraaj" + inputString
})
Trying which compiler complains :(
Please suggest if I am doing any thing wrong.
Think about the difference between declaring an object and then using it:
var a = 100
abs(a)
vs using it directly:
abs(100)
Same difference applies between declaring then using a function:
func talk(x: String) { return x + " is talking" }
doThis(talk)
vs using it directly:
doThis( { x: String -> return x + " is talking" } )
Writing
doThis( func talk(x: String) { return x + " is talking" } )
is like writing
abs(var a = 100)
which doesn't make sense.
You can, but avoid the func keyword, that is, avoid declaring a fun, but use the anonymous nature of closures:
modifyString(" is learning swift", { inputString in "Miraaj" + inputString })
See http://fuckingswiftblocksyntax.com

Generic function using an interface

Since I've a similar function for 2 different data types:
func GetStatus(value uint8) (string) {...}
func GetStatus(name string) (string) {...}
I would want to use a way more simple like:
func GetStatus(value interface{}) (string) {...}
Is possible to create a generic function using an interface?
The data type could be checked using reflect.Typeof(value)
Does what you want to do need the complexity and overhead of the reflect package? Have you considered a simple switch statement type switch?
package main
import (
"fmt"
)
func GetStatus(value interface{}) string {
var s string
switch v := value.(type) {
case uint8:
v %= 85
s = string(v + (' ' + 1))
case string:
s = v
default:
s = "error"
}
return s
}
func main() {
fmt.Println(GetStatus(uint8(2)), GetStatus("string"), GetStatus(float(42.0)))
}