disconnecting a manifold stream without closing other streams - clojure

If I create two streams and connect the two:
(def a (stream/stream))
(def b (stream/stream))
(stream/connect a b)
When 'a' is closed 'b' closes
(stream/closed? b) => false
(stream/close! a)
(stream/closed? b) => true
Is there a way to disconnect 'a' from 'b' without closing 'b'?

Yes, there is. According to the doc of stream/connect:
Optionally takes a map of parameters:
...
downstream? - if closing the source will close the sink. Defaults to true.
...
So, you need to connect your streams as follows:
(stream/connect a b {:downstream? false})

Related

Make a vscode snippet that can use a variable number of arguments

I am new to VSCode. Thinking about code snippets, I looked around for a way to kind of script inside the snippet. I mean to do more than just fill or transform a variable. For example...
This is a simple snippet. I am going to type rci for the class initializer. When I enter the method arguments I would like the assignment and documentation + some other things to happen.
rci<tab> and then def initialize(a, b)) to result in something like this...
attr_reader :a
attr_reader :b
# #param a [...] ...
# #param b [...] ...
def initialize(a, b)
#a = a
#b = b
end
Is it possible? How can it be achieved? There could be any number of arguments. And each argument would trigger another line of the class initializer.
"Class Initializer": {
"prefix": "rci",
"body": [
"${1/([^,]+)([,\\s]*|)/attr_reader :$1\n/g}",
"${1/([^,]+)([,\\s]*|)/# #param $1 [...]${2:+\n}/g}",
"def initialize($1)",
"${1/([^,]+)((,\\s*)|)/\t#$1 = $1${2:+\n}/g}",
"end"
],
"description": "Initialize Class"
}
The key to get it to work for any number of method arguments is to get them into the same regex capture group.
Then, with the global flag set, each capture group will trigger the replacement text. So for instance, /attr_reader :$1\n/g will get triggered 3 times if you have 3 method arguments.
You will see this ${2:+\n} in the transforms above. That means if there is a capture group 2, add a newline. The regex is designed so that there is only a capture group 2 if there is another , between arguments. So a final ) after the last argument will not trigger another newline - so the output exactly matches your desired output as to newlines (but you could easily add or remove newlines).
Your input must be in the correct form:
v1, v2, v3
Here is a demo:
So again the necessary form is just v1 v2 v3. There doesn't need to be a space between the arguments but then you would get def initialize(v1,v2,v3) without spaces either.
Hit Tab after the final argument to trigger completion.
It turns out snippets are pretty powerful!!
For a similar question about using multiple arguments, see VSCode snippet: add multiple objects to a class constructor

Run every N minutes or if item differs from average

I have an actor which receives WeatherConditions and pushes it (by using OfferAsync) it to source. Currently it is setup to run for each item it receives (it stores it to db).
public class StoreConditionsActor : ReceiveActor
{
public StoreConditionsActor(ITemperatureDataProvider temperatureDataProvider)
{
var materializer = Context.Materializer();
var source = Source.Queue<WeatherConditions>(10, OverflowStrategy.DropTail);
var graph = source
.To(Sink.ForEach<WeatherConditions>(conditions => temperatureDataProvider.Store(conditions)))
.Run(materializer);
Receive<WeatherConditions>(i =>
{
graph.OfferAsync(i);
});
}
}
What I would like to achieve is:
Run it only once every N minutes and store average value of WeatherConditions from all items received in this N minutes time window
If item received matches certain condition (i.e. item temperature is 30% higher than previous item's temperature) run it despite of being "hidden" in time window.
I've been trying ConflateWithSeed, Buffer, Throttle but neither seems to be working (I'm newbie in Akka / Akka Streams so I may be missing something basic)
This answer uses Akka Streams and Scala, but perhaps it will inspire your Akka.NET solution.
The groupedWithin method could meet your first requirement:
val queue =
Source.queue[Int](10, OverflowStrategy.dropTail)
.groupedWithin(10, 1 second)
.map(group => group.sum / group.size)
.toMat(Sink.foreach(println))(Keep.left)
.run()
Source(1 to 10000)
.throttle(10, 1 second)
.mapAsync(1)(queue.offer(_))
.runWith(Sink.ignore)
In the above example, up to 10 integers per second are offered to the SourceQueue, which groups the incoming elements in one-second bundles and calculates the respective averages of each bundle.
As for your second requirement, you could use sliding to compare an element with the previous element. The below example passes an element downstream only if it is at least 30% greater than the previous element:
val source: Source[Int, _] = ???
source
.sliding(2, 1)
.collect {
case Seq(a, b) if b >= 1.3 * a => b
}
.runForeach(println)

Select By NULL values in DAS Stream

I have a stream with multiple attributes. Lets assume name of the stream is "MyStream" and it is imported to the execution plan as "my". Names of attributes are "A" and "B". "B" attribute can have NULL values. I want to select Both "A" and "B" where "B" is NULL. I try Bellow code.
FROM my[B is null]
SELECT A as A,B as B
INSERT INTO out;
But the "out" stream is always empty. "B"s data type is FLOAT. What is the problem in my code?
I try bellow code and it worked for me.
FROM my
SELECT A as A,
ifThenElse(B is null,convert(0.1,'FOLAT'),B) as B
INSERT INTO out;

Cond If And Or in Racket

Can someone please explain these functions for me in racket. I`m totally lost. Please help me with some examples. Thanks! I just cannot figure these functions out for the life of me.
First, the If:
(if (positive? 1) 1 -1)
Racket first evaluates if 1 is positive (which is the first expresion (positive? 1)). If it is, returns 1, else, return -1. This is equivalent to c-like languages doing:
if ( positive?(1))
return 1
else
return -1
The Cond is basically a if that has multiple options. The equivalent in C-like languages would be else-if
(cond [(first-condition) (what-to-do)]
[(second-condition) (what-to-do)]
[(third-condition) (you-get-the-idea)])
And and Or are just the logical operators, equivalent to && and || in C-like languages
(and true true) => true
(and true false) => false
(or true true) => true
(or true false) => true
(or false false) => false
If is the turnary operator. It has three arguments, unless the first argument has a value of #f it will return the value of the second argument, otherwise the value of the third argument.
OR accepts one or more arguments, evaluates them one at a time left to right, and returns the first value if finds that is not #f, and returns #f if no argument satisfies that condition.
AND accepts one or more arguments evaluate them one at a time left to right, if it finds one that is #f it returns #f, otherwise it returns the value of the last argument that it evaluates.
COND accepts one or more arguments, each with one or more sub arguments (2 is the usual number though). It evaluates each argument left to right one at a time by evaluating the first subargument. If it is not #f then it evaluates each of the rest of the sub-arguments (if any) in order and returns the value of the last argument. Otherwise it moves onto the next argument and evaluates it the same way. else is a special sytax within these sub-arguments that is always treated as if it is not #f.
And here argument is understood to mean any valid s-expression.
NB: If you are familiar with non-lisp languages this is the answer for you. I'm not trying to explain them in other way than other code. Other answers do however so this is just a supplement.
None of those are functions, but special forms.
(if predicate
consequent
alternative)
is pretty much like Algol-dialects if
if( predicate )
{
consequent
}
else
{
alternative
}
Note that predicate, consequent and alternative can be anything from a complex expression to a simple value.
cond works more like an if, elseif..., else:
(cond (predicate1 consequent1)
(predicaten consequentn)
(else alternative))
and works like && in algol dialects. Thus false && print("Do it!") doesn't print anything since it short circuits.
(and #f (display "Do it!")) ; ==> #f (and does not display anything since first term was false)
(and 1 2 3) ; ==> 3 (3 is the last true value. In Scheme everything except #f is true.)
or works like || in algol dialects. thus true || print("Do it!") doesn't print since first term was true.
(or 'mama (display "Do it")) ; ==> mama (first true value, does not print "do it")

Sockets in Swipl

So I'm currently in the starting phase of building a game and I'm using prolog as the server side of the game to do validation checks of plays in a board.
I'm having two issues at the moment.
One:
Can't seem to close the server without aborting and thus leaving the socket open.
Code is as follows
Server:
:- use_module(library(socket)).
create_server(Port) :-
tcp_socket(Socket),
tcp_bind(Socket, Port),
tcp_listen(Socket, 5),
tcp_open_socket(Socket, AcceptFd, _),
dispatch(AcceptFd).
dispatch(AcceptFd) :-
tcp_accept(AcceptFd, Socket, Peer),
thread_create(process_client(Socket, Peer), _,
[ detached(true)
]),
dispatch(AcceptFd).
process_client(Socket, _Peer) :-
setup_call_cleanup(tcp_open_socket(Socket, In, Out),
handle_service(In, Out),
close_connection(In, Out)).
close_connection(In, Out) :-
close(In, [force(true)]),
close(Out, [force(true)]).
handle_service(In, Out) :-
read(In, Int),
writeln(Int),
( Int == end_of_file
-> true
;
call_test(Int,Term),
format(Out, 'seen(~q).~n', [Term]),
flush_output(Out),
handle_service(In, Out)
).
call_test(test,Term):-Term = 'really test'.
call_test(validate(teste),Term):-
String = "validate(test)",
string_to_list(String,List),
read_from_chars(List,Stringf),
writeln(Stringf),
Term = 'foo'.
Client:
:- use_module(library(streampool)).
create_client(Host, Port) :-
setup_call_catcher_cleanup(tcp_socket(Socket),
tcp_connect(Socket, Host:Port),
exception(_),
tcp_close_socket(Socket)),
setup_call_cleanup(tcp_open_socket(Socket, In, Out),
chat_to_server(In, Out),
close_connection(In, Out)).
chat_to_server(In, Out) :-
read(Term),
( Term == end_of_file
-> true
; format(Out, '~q .~n', [Term]),
flush_output(Out),
read(In, Reply),
write(Reply),
%format('Reply: ~q.~n', [Reply]),
chat_to_server(In, Out)
).
close_connection(In, Out) :-
close(In, [force(true)]),
close(Out, [force(true)]).
I can close the client with no issues using ctrl+D (which is end_of_file), but my server doesn't close... It receives end_of_file, it prints end_of_file but it doesn't close. Not even when inserting it directly into the server. What am I doing wrong?
Two: I need to pass a string from C++ to Swipl that has the name of the predicate to use and the arguments. Can someone please tell me how to do this or at least point me in the right direction?
Thank you very much.
Shouldn't Int == end_of_file be Int = end_of_file, to check unification? I might be wrong here, I use sicstus.
As for how pass a predicate name and arguments, something like this should work
call_test(Request, Answer) :-
Request = Pred(Arg1, Arg2, Arg3),
Request,
Answer = somethingHere.
Then in C++ simply do
//pseudo-code
write(socket, "myPredicate(myArg1, myArg2, myArg3).\n");
Prolog will convert the incoming string into actual code if you tell it to.
An alternative, more generic, implementation is
call_test(Request, Answer) :-
Pred =.. Request,
Pred,
Answer = somethingHere.
and in C++
write(socket, "[myPredicate, Arg1, Arg2, Arg3].\n");
//supports variable number of args
One: You can solve that in a simple way or a complicated way. The simple way is restarting not just your server, but also the Prolog interpreter. The complicated one is calling a predicate that cleanly exits the program when a "close" message is received.
Two: The read/2 predicate, which takes as parameters an input stream (the read end of your socket, in this case) and a variable where the parsed input will be put, does just what you want: it reads a term from the input and converts it to the Prolog term it represents, as if you'd written it in a Prolog program. Note that after the term, the input must contain a dot to tell Prolog the term has ended (as the other answer shows).