I use GraphViz with the following dot file:
digraph G
{
rankdir=LR;
subgraph commits
{
"5c071a6b2c" -> "968bda3251" -> "9754d40473" -> "9e59700d33" -> "2a3242efa4";
}
subgraph annotations
{
"V1.0" [shape=box];
"br/HEAD" [shape=box];
"V1.0" -> "9e59700d33" [weight=0];
"br/HEAD" -> "2a3242efa4" [weight=0];
}
}
It give me something like that:
But I want something like that:
V1.0 br/HEAD
| |
\/ \/
5c071a6b2c -> 968bda3251 -> 9754d40473 -> 9e59700d33 -> 2a3242efa4
How can I do that?
For your help,
Thanks by advance.
This will align the annotations with the commits:
digraph G
{
rankdir=LR;
subgraph commits
{
"5c071a6b2c" -> "968bda3251" -> "9754d40473" -> "9e59700d33" -> "2a3242efa4";
}
subgraph annotations1
{
rank="same";
"V1.0" [shape=box];
"V1.0" -> "9e59700d33" [weight=0];
}
subgraph annotations2
{
rank="same";
"br/HEAD" [shape=box];
"br/HEAD" -> "2a3242efa4" [weight=0];
}
}
Since the rank="same"; effects the whole subgraph I had to split the annotations in two different subgraphs.
Result is:
Related
I'm new at Haskell and Alex.
I'm trying to make tokens of operators in Lexer.x
here is an example of my code
\<= { \s -> TLE }
\== { \s -> TEQ }
\/= { \s -> TNEQ }
\&& { \s -> TAND }
but when I wrote
\|| { \s -> TOR }
I got a parse error on this line
How I should make token for || ?
You can use string literals to prevent escaping all characters, so you can use:
"||" { \s -> TOR }
I've got this section of code:
class Main {
static inline function difference(a:Int, b:Int, ?f:(Int, Int) -> Int):Int {
if (f == null) {
f = (a, b) -> a - b;
}
return f(a, b);
}
static function main() {
trace(difference(42, 37));
trace(difference(42, 37, (a, b) -> a - b));
}
}
Which, when I compile using haxe --main Main, fails with this error:
Main.hx:11: characters 15-50 : Cannot modify a closure parameter inside inline method
Main.hx:11: characters 15-50 : For function argument 'v'
If I change Main.difference to not be inline, this error doesn't come up and everything compiles fine.
Why does this error occur?
Edit: I've found out I can also assign the argument to a variable first, and then pass the variable to Main.difference, like this:
static function main() {
var f = (a, b) -> a - b;
trace(difference(42, 37, f));
}
Which works fine with Main.difference being inlined. How does assigning the function to a variable first change things though?
This is related to how inline functions are unwrapped by the compiler. Let us take a simpler variant of your code:
class HelloWorld {
static inline function difference(a:Int, b:Int, ?f:(Int, Int) -> Int):Int {
return f(a, b);
}
static function main() {
trace(difference(42, 37, (a, b) -> a - b));
}
}
When disabling optimizations, this will yield the following JavaScript:
HelloWorld.main = function() {
console.log("HelloWorld.hx:14:",(function(a,b) {
return a - b;
})(42,37));
};
So the body of difference has been incorporated into main using a JavaScript closure. My best guess for what is happnening in your exact case is something like this:
HelloWorld.main = function() {
var v = function(a,b) {
return a - b;
}
console.log("HelloWorld.hx:14:", (function(a,b) {
if (v == null) {
v = function(a, b) {
return a - b;
}
}
return v(a, b);
})(42, 37));
};
This alters the value of v, which exists outside of difference, which has been automatically placed there as a binding for the anonymous lambda. This is what the compiler is trying to avoid. This would not be the end of the world in your case, but in general this is bad and would lead to issues in many programs.
There is a way to inline this code perfectly by hand without this, but I think that there is some weirdness surrounding how annonymous lambdas are currently handled. The situation may improve in the future.
When you explicitly defined f in main, the compiler is intelligent enough to rename the nested f as f1, which is why the issue does not occur:
HelloWorld.main = function() {
var f = function(a,b) {
return a - b;
};
var f1 = f;
if(f1 == null) {
f1 = function(a,b) {
return a - b;
};
}
console.log("HelloWorld.hx:14:",f1(42,37));
};
But this would also work if the inline part of this function is important to you:
class HelloWorld {
static inline function difference(a:Int, b:Int, ?f:(Int, Int) -> Int):Int {
var h = f;
if (h == null) {
h = (a, b) -> a - b;
}
return h(a, b);
}
static function main() {
trace(difference(42, 37, (a, b) -> a - b));
}
}
how can I add logs if file is transferred successfully.
I want to log file name and some values form my config object
return IntegrationFlows.from(Sftp.inboundAdapter(inboundSftp)
.localDirectory(this.getlocalDirectory(config.getId()))
.deleteRemoteFiles(true)
.autoCreateLocalDirectory(true)
.remoteDirectory(config.getInboundDirectory()), e -> e.poller(Pollers.cron("0 */1 * ? * *").errorChannel(MessageHeaders.ERROR_CHANNEL).errorHandler((ex) -> {
try {
// exception handling here
})))
.handle(Sftp.outboundAdapter(outboundSftp)
.useTemporaryFileName(false)
.autoCreateDirectory(true)
.remoteDirectory(config.getOutboundDirectory()), c -> c.advice(startup.deleteFileAdvice())
)
.get();
Update
after Gary Russell answer, my working code is
return IntegrationFlows.from(Sftp.inboundAdapter(inboundSftp)
.localDirectory(this.getlocalDirectory(config.getId()))
.deleteRemoteFiles(true)
.autoCreateLocalDirectory(true)
.remoteDirectory(config.getInboundDirectory()), e -> e.poller(Pollers.cron("0 */1 * ? * *").errorChannel(MessageHeaders.ERROR_CHANNEL).errorHandler((ex) -> {
// action on exceptions are here
}))).publishSubscribeChannel(s -> s
.subscribe(f -> f
.handle(Sftp.outboundAdapter(outboundSftp)
.useTemporaryFileName(false)
.autoCreateDirectory(true)
.remoteDirectory(config.getOutboundDirectory()), c -> c.advice(startup.deleteFileAdvice())
))
.subscribe(f -> f
.handle(m -> {
// all my custom logging logic is here
})
))
.get();
Add a .publishSubscribeChannel() channel with 2 subflows. Docs here.
.publishSubscribeChannel(s -> s
.subscribe(f -> f
.handle(...)
.subscribe(f -> f
.log())
I have a swift implementation of the haskell <*> operator that seems to work as long as the arguments are arrays:
public func <*> <T, U>(left:[(T)->U], right:[T]) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
I'm trying to make it more general by rewriting it to use sequences instead of arrays, but I'm having difficulty with the syntax to require that a sequence be a sequence of functions. This works to generalize the right argument, but not the left:
public func <*> <T, U, Tseq:SequenceType where Tseq.Generator.Element == T>(left:[(T)->U], right:Tseq) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
Now I'm trying to generalize the left part, but running into syntax errors. It seems like it ought to be:
public func <*> <
T,
U,
Tseq:SequenceType where Tseq.Generator.Element == T,
Fseq:SequenceType where Fseq.Generator.Element == (T) -> U
>(left:[(T)->U], right:Tseq) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
But that gives me an error on the Fseq... line:
Expected '>' to complete generic parameter list
What is the proper syntax (or is there no proper syntax) to require that Fseq.Generator.Element be a function taking a T and returning a U?
Couple of problems (one fixable, one more fatal):
You have the syntax for the generic template a bit off. There’s only one where clause for all the placeholders, rather than an optional one per placeholder. So it would be more like:
public func <*> <
T, U, Tseq: SequenceType, Fseq: SequenceType
where Fseq.enerator.Element == T -> U,
Tseq.Generator.Element == T>
(left:[(T)->U], right:Tseq) -> [U] {
return flatten(map(left) { (function) -> [U] in
return map(right) { return function($0) }
})
}
However, that still won’t work because you can’t have expressions more complex than single types on the rhs of a == (not even tuples of two placeholders). So where Fseq.Generator.Element == T->U is not going to fly.
You might want to look at how swiftz does this – looks like it requires an additional struct.
I compile a large song book, and for that I would like to have many local definitions of functions, that will, in the end, be in an \include d file, but that makes no difference here. For this, I need to define the functions inside \score{ ... } scope. However, LilyPond keeps throwing errors.
The non-working example:
\version "2.17.26"
\book {
\header {
title = "This is a book"
}
\score {
xyz = { a' b' c'' }
abc = #(define-music-function
( parser location musicnotes )
( ly:music? )
#{
c' $musicnotes e'
#}
)
{ \abc { d' } f' \xyz }
\header {
piece = "First piece"
opus = "op. 1024"
}
}
\score {
xyz = { a' a' a' }
abc = #(define-music-function
( parser location musicnotes )
( ly:music? )
#{
e' $musicnotes c'
#}
)
{ \abc { d' } f' \xyz }
\header {
piece = "Second piece"
opus = "op. 1025"
}
}
}
Throws an error:
test.ly:10:17: error: unrecognized string, not in text script or \lyricmode
xyz = { a' b' c'' }
The following works, however, I have to give the functions unique names, which is frowned upon.
\version "2.17.26"
xyz = { a' b' c'' }
abc = #(define-music-function
( parser location musicnotes )
( ly:music? )
#{
c' $musicnotes e'
#}
)
xxyz = { a' a' a' }
aabc = #(define-music-function
( parser location musicnotes )
( ly:music? )
#{
e' $musicnotes c'
#}
)
\book {
\header {
title = "This is a book"
}
\score {
{ \abc { d' } f' \xyz }
\header {
piece = "First piece"
opus = "op. 1024"
}
}
\score {
{ \aabc { d' } f' \xxyz }
\header {
piece = "Second piece"
opus = "op. 1025"
}
}
}
Unfortunatey, it's not possible to stick assignments in a score. You can only put assignments in the following places:
the top level,
inside \display, \header, and \midi blocks
The LilyPond grammar makes this quite clear, even if the rest of the manual is a bit evasive about it. (Look at http://lilypond.org/doc/v2.17/Documentation/contributor/lilypond-grammar , and look for where the assignment rule gets used).
Assuming your assignments are not appropriate for the blocks listed above (which is definitely the case in this example), and assuming that you don't want to do something exotic like go and define your own Scheme modules and figure out how to use them in your LilyPond file, you have two choices:
Define xyz and abc, then define the music that will go into the first score. Then redefine xyz and abc before defining the music for the next score. This works because assignments overwrite whatever was previously there, and because LilyPond defines are generally processed in order. However, if you want some of your defines to be used in both scores and to be the same, you may get confused.
Settle for your approach, though I would pick a prefix or a suffix that makes it clearer which score the define goes with.
The first option would look something like this:
\version "2.18.0"
xyz = { a' b' c'' }
abc = #(define-music-function (parser location musicnotes)
(ly:music?)
#{ c' $musicnotes e' #})
smus_a = { \abc { d' } f' \xyz }
xyz = { a' a' a' }
abc = #(define-music-function (parser location musicnotes)
(ly:music?)
#{ e' $musicnotes c' #})
smus_b = { \abc { d' } f' \xyz }
\book {
\header {
title = "A Book!"
}
\score {
\smus_a
\header { piece = "First piece" }
}
\score {
\smus_b
\header { piece = "Second piece" }
}
}
This also works if the music-defining parts are refactored out into separate LilyPond source files.
It is possible!
But you have to define a command to define the variable or command:
parserDefine =
#(define-void-function (parser location name val)(symbol? scheme?)
(ly:parser-define! parser name val))
This is a void-function and can be called almost anywhere:
\score {
{
% you have to be in your music-expression
\parserDefine xyz { a' a' a' }
% There must be something between parserDefine and the call!
c'' \xyz
\parserDefine abc #(define-music-function
( parser location musicnotes )
( ly:music? )
#{
c' $musicnotes e'
#}
)
a' \abc d'
}
}
If the command is defined, you can call inside your music expressions. After you have done so, the parser needs a little lookahead, so that the variable really is available - here its the c''. You can optionally wrap the expression in another pair of curly braces.