For a homework project I am building a Typesafe LINQ framework in Typescript, here is the project description: Project
The description says: "Your project will generate a chain of executable functions, in the lazy style."
But I don't know exactly what Lazy means here?
I have build a Table containing all the operators, but the problem is that all the functions return a result immediately.
interface Table<T, U> {
readonly data: Pair<List<T>, List<U>>
Select: <K extends keyof T>(this: Table<T, U>, properties: K[]) => Table<Omit<T, K>, Pick<T, K> & U>
}
const Table = <T, U>(data: Pair<List<T>, List<U>>): Table<T, U> => ({
data: data,
Select: function <K extends keyof T>(this: Table<T, U>, properties: K[]): Table<Omit<T, K>, Pick<T, K> & U> {
let selection = this.data.First.map(entry => pickMany(entry, properties))
let result = this.data.map(
first => first.map(entry => omitMany(entry, properties))
,
second => merge_list_types(second.zip(selection))
)
return Table(result)
},
})
So my basic understanding of Lazy is that the operators should return a executable function, that will be called later in the program. But I don't know how to do that.
Also the teachers provided me with a wrapper for a function:
export interface Func<a, b> {
f: (_: a) => b
then: <c>(this: Func<a, b>, g: Func<b, c>) => Func<a, c>
}
export let Func = <a, b>(f: (_: a) => b): Func<a, b> => {
return {
f: f,
then: function <c>(this: Func<a, b>, g: Func<b, c>): Func<a, c> {
return Func<a, c>(x => g.f(this.f(x)))
},
}
Should I just return a Func<Table<Something, Something>, Table<AnotherThing, AnotherThing>>, for every operator to make it lazy? I am not sure, seems like a decent solution. But I can use some help in the understanding of Lazy style programming.
Lazy, in the context of porting LINQ, means returning an object that does work when iterated over, rather than doing some work iterating over your input data to generate iterable output data.
As an example
Print(allNumbers.Where(isEven).Take(10))
If Where is Eager, this takes infinite time, enumerating every number. If Where is Lazy, it only enumerates numbers up to 20.
Related
Let's say I have class:
class Foo {
fun doSomething(param1: Int, param2: String, param3: String)
}
and a data class
data class Params(
val param1: Int,
val param2: String,
val param3: String)
Now I want to use the data class arguments to send them to the function, is there a way to do that? Lets say something similar to:
val myParams = Params(1, "2", "3")
val foo = Foo()
foo.doSomething(myparams)
Or by some sort of transformation or method naming. as:
execute(foo, foo::doSomething, myParams)
I doubt this is possible in Kotlin without some tricks. Possible solutions are reflection API and code generation.
Example using reflection:
fun main() {
val myParams = Params(1, "2", "3")
val foo = Foo()
invokeWithParams(foo::doSomething, myParams)
}
fun <T : Any, R> invokeWithParams(func: KFunction<R>, params: T): R {
val paramValues = func.parameters.map { kparam ->
(params::class as KClass<T>)
.memberProperties
.single { it.name == kparam.name }
.get(params)
}.toTypedArray()
return func.call(*paramValues)
}
It should work for static functions, member functions, and extension functions. It may fail with some rarer cases. You should probably add some error handling, e.g. checks if params match.
It won't work on anything else than JVM as reflection is still very limited on other targets.
Also, I'm not entirely sure about this unsafe cast. I think it can't fail, but I'm not 100% sure about it.
Update:
We can make it a little more funny by converting the function to extension operator invoke:
operator fun <T : Any, R> KFunction<R>.invoke(params: T): R
Then we can use it with any function like this:
(foo::doSomething)(myParams)
I'm not sure if this is a good idea though as it is more confusing than an explicit call to the utility function.
coming from rspec, i am having trouble understanding mocking with jest. the approach i am trying for, is to automock a class's constructor and all of it's functions, and then unmock them one by one to test only that one function. the only documentation i can find on it, is with using 2 classes, mocking 1 class, and then testing that those functions are called from the other unmocked class.
below is a basic, contrived idea of what i am trying to do. can someone direct me to the jest-way of doing this?
foo.js
class Foo
constructor: ->
this.bar()
this.baz()
bar: ->
return 'bar'
baz: ->
return 'baz'
foo_test.js
// require the class
Foo = require('foo')
// mock entire Foo class methods
jest.mock('foo')
// unmock just the bar method
jest.unmock(Foo::bar)
// or by
Foo::bar.mockRestore()
// and should now be able to call
foo = new Foo
foo.bar() // 'bar'
foo.baz() // undefined (still mocked)
// i even tried unmocking the instance
foo = new Foo
jest.unmock(foo.bar)
foo.bar.mockRestore()
mockFn.mockRestore() worked for me with jest#24.9.0:
// Create a spy with a mock
const consoleInfoSpy = jest.spyOn(console, 'info').mockImplementation(() => {})
// Run test or whatever code which uses console.info
console.info('This bypasses the real console.info')
// Restore original console.info
consoleInfoSpy.mockRestore()
This does not strictly apply to the OP, but answer-seekers may end up here. You can mock a module except certain parts for all tests like so.
mocks/saladMaker.js
// Let Jest create the mock.
const saladMaker = jest.genMockFromModule('../saladMaker');
// Get the unmocked chop method.
const {chop} = jest.requireActual('../saladMaker');
// Patch it in.
saladMaker.chop = chop;
module.exports = saladMaker;
The key part is to use requireActual to get at the unmocked module.
bypassing module mocks
It is not possible to get the original module after mocking it in Jest. What jest.mock does is to replace the module with your mock.
So even you write:
Foo = require('foo')
jest.mock('foo')
Jest will hoist the jest.mock('foo') call on top of the call stack, so it's the first thing that happens when the test starts. This will also affect all other modules you import and that import foo.js.
You could try to use spyOn to spy on functions of an object, should work with classes as well, but I'm not quite sure.
I have tried a lot of things, but what eventually worked for me is (using Create React App):
setupTests.ts
jest.mock("./services/translations/translationsService", () => ({
__esModule: true,
default: {
initDict: (): void => undefined,
translate: (key: Phrases): string => key,
},
t: (key: Phrases): string => key,
}));
Which mocks the module for all tests. In order to unmock for a single test suite, I did:
jest.mock("../../../services/translations/translationsService", () =>
jest.requireActual("../../../services/translations/translationsService")
);
describe(() => { /* test suite goes here and uses real implementation */ });
For Jest#27.4.7
const mockChildComponent = jest.mock('../../../src/components/common/childComponent', () => ({
__esModule: true,
default: (props: Prop) => (
<div data-test-id="stub-chart-panel">
{props.label}
</div>
),
}));
test('mock child', async () => {
const wrapper = mount(
<ParentComponent />
);
expect(....);
});
mockChildComponent.restoreAllMocks();
test('default child component ', async () => {
const wrapper = mount(
<ParentComponent />
);
expect(....);
});
I've just started Scala and am tinkering in worksheets. For example:
def merp(str: String) : String = s"Merrrrrrrp $str"
val merp2 = (str: String) => s"Merrrrrrrp $str"
val merp3 = (str: String) => merp(str)
val merp4 = merp _
merp("rjkghleghe")
merp4("rjkghleghe")
And the corresponding worksheet results:
merp: merp[](val str: String) => String
merp2: String => String = <function1>
merp3: String => String = <function1>
merp4: String => String = <function1>
res0: String = Merrrrrrrp rjkghleghe
res1: String = Merrrrrrrp rjkghleghe
Saying, for example, val merp5 = merp produces an error, because apparently methods cannot be values the way functions can. But I can still pass methods as arguments. I demonstrate this in the following code snippet, adapted from a similar SO question:
def intCombiner(a: Int, b: Int) : String = s"herrrrrrp $a derrrrrrp $b"
def etaAbstractor[A, B](combineFoo: (A, B) ⇒ String, a: A, b: B) = combineFoo(a, b)
etaAbstractor(intCombiner, 15, 16)
worksheet result:
intCombiner: intCombiner[](val a: Int,val b: Int) => String
etaAbstractor: etaAbstractor[A,B](val combineFoo: (A, B) => String,val a: A,val b: B) => String
res10: String = herrrrrrp 15 derrrrrrp 16
Is methods-not-being-first-class a limitation, perhaps imposed by Scala's JVM interaction, or is it a decision in the language's design?
Why do I need to roll my own eta abstractions, as in merp3?
Is merp4 also an eta abstraction, or is it something sneakily similar?
Why does my etaAbstractor work? Is Scala quietly replacing intCombiner with intCombiner _?
Theoretical, computer sciencey answers are welcome, as are pointers to any relevant points in the language specification. Thanks!
Disclaimer: I'm not a computer scientist, but I will try to guess:
Method is a part of an object and doesn't exist outside of it. You can't pass method alone. Closure is another (equivalent?) way of encapsulating state, by converting an object method to a standalone function (which is by the way just another object with apply() method in Scala) you are creating a closure. This process is known as eta-expansion. §3.3.1, §6.26.5
You don't have to. You can also write val merp3 : (String => String) = merp. §6.26.5
Yes, merp4 is eta-expansion too. §6.7
§6.26.2
The reason it works with etaAbstractor is that the compiler can infer that a function (not a function invocation) is required.
If I had to guess why the underscore is required where a function type cannot be inferred, I'd think that it's to improve error reporting of a common class of errors (getting functions where invocations are intended). But again, that's just a guess.
In the JVM, a method is not an object, whereas a first-class function must be one. So the method must be boxed into an object to convert it to a function.
My problem is quite simple : I want to have an implicit conversion of value to function if they are not already function. I plan to use a type safe pattern by requesting the instantiation of an implicit parameter (if the valueis a function the implicit creation fails).
However I do not see how to test that a value is not a function
I learned type safe pattern from user Beryllium in one of my previous question. See :
Type safe method chaining that doesn't allow repeats of operations
The implicit I've implemented is working, but too well. I want to transform not function expression to specific-application-default function automatically
implicit def defaultExecutionUnitParameterNReturn(a: Any): Unit => MyDefaultReturn =
{u : Unit => a }.andThen(_ => defaultReturn())
However my application would fail if the user implements "a" as a function
So my first idea was something like
implicit def defaultExecutionUnitParameterNReturn[A](a: A)(implicit e : A =!= Function) Unit => MyDefaultReturn =
{u : Unit => a }.andThen(_ => defaultReturn())
where implicit =!=[A,B] fails if A and B are the same type.
But "Function" does not exists
You need to place your implicit conversions in 2 traits
trait Implicits extends ImplicitsLow {
implicit def convertFunction[T, R](f: T => R) = ???
}
trait ImplicitsLow {
implicit def convert[T](t: T) = ???
}
Then you can observe that the function conversion is used in preference to the value one:
val result1: String = (i: Int) => i + 1
val result2: String = 1
// prints (function, value)
println((result1, result2))
Investigate below code snipped. This is standard implicit convertion example. toFunnction0 takes anything and converts it into Function0[R] or just simplified () => R.
implicit def toFunnction0[R](r: => R): Function0[R] = () => r
def iWantFunction0(f0: () => String) = {
f0()
}
def testFun = {println("computing string in testFun..."); "ABC"} //every time when called block of code will run
val abcVal = "ABC" //this is computed only once
iWantFunction0(testFun)
//here abcVal is not a function, so implicit works.
//toFunnction0 is in scope, so compiler will translate it into
//iWantFunction0(toFunnction0(abcVal))
iWantFunction0(abcVal)
If I have the following code:
val wows = Buffer[Wow]()
def yo(f: _ => Wow) { wows += f }
and I get an error when trying to add f. I wonder, how can I use f inside the method body, or more precisely, how should I refer to it since f or f() or f(_) do not work.
UPDATE:
The type of f cannot be changed to f: => Wow because the functions of type _ => Wow passed to this method come from such a class:
object Wonderful {
val wows = Buffer[Wow]()
def yo(f: _ => Wow) { wows += f }
}
class Joy[+R](fs: Buffer[_ => R]) {
def exalt() {
fs.map(Wonderful.yo(_))
}
}
and that buffer cannot be parametrized with => R, it shows an error.
UPDATE 2: Both of you have second-answered before I have finished the explanation of the second part! Thanks! That's the speed!
UPDATE 3: Basically, I am learning Scala and I am trying to try out all that I can think of. In this particular piece of code, there happens the following thing: I have 3 basic classes:
WorldObject - represents all game objects (has x, y and such).
Emitter - represents something that emits objects over time (extends WorldObject).
Funset - a set of functions that should produce WorldObjects when called. In future I wanted to make them partially applied functions with some prepared arguments, passed directly to the corresponding factory methods.
World - where everything takes place.
The main point is that a Funset's collection of "generative" functions can be edited during runtime, that is why it is represented as buffer. On every update cycle an Emitter passes each of Funsets functions to the World's creator functions that manifest the generated objects in the world.
I hope I have explained so it can be understood... maybe a little bizzare or a wrong architecture, but.. anyways, I have learned something about Scala now!
Is it by-name parameter you are after? If so, your syntax is a bit off. Here is the correct way:
scala> class Wow
defined class Wow
scala> val wows = collection.mutable.Buffer.empty[Wow]
wows: scala.collection.mutable.Buffer[Wow] = ArrayBuffer()
scala> def yo(f: => Wow) { wows += f }
yo: (f: => Wow)Unit
_ => Wow is a method that takes a single argument of a type that you don't know and returns a Wow. You won't be able to call it since you don't know what sort of argument to call it with!
I suspect you want a method with no arguments, which you could do like the following:
def yo( f: () => Wow ) { wows += f() }
Also you can do a by-name parameter which is a little bit more implicit:
def you( f: => Wow ) { wows += f }
Edit: The difference is in how you call it; a by-name parameter just evaluates an expression when it is used. Passing a function is actually just passing a function which you can call at will.