Can't create simple binary data structure with IdrisNet2 - idris

I am trying to use the IdrisNet2 library to define some binary data structures. I am using Idris 0.9.17.1 and commit 262b746c9a2405e43d1de6a48de44cac2fd19932 of IdrisNet2. I am defining a packet with one 16 bit field:
module Main
import IdrisNet.PacketLang
import Data.So
myPacket : PacketLang
myPacket = with PacketLang do
bits 16
main : IO ()
main = putStrLn "hello"
I get the compiler error:
Can't solve goal
So (fromInteger 16 > fromInteger 0)
What exactly is the problem and how can I fix it? I am guessing that I need to prove to the compiler that 16 is greater than 0, but I'm not sure how to do this in Idris or why this is necessary.

Sorry about that. A while back we decided to standardize on uppercase for all the types and their constructors; that meant oh and so got renamed to Oh and So. So there was an update to this lib to get it to compile, but it looks like an oh in the default tactics to solve an implicit param got overlooked:
https://github.com/SimonJF/IdrisNet2/blob/master/src/IdrisNet/PacketLang.idr#L149
So that tactic would always fail (oh is an undefined reference). You could explicitly pass the value of p there, and that would work: bits 16 {p = Oh}.
But I've submitted a pull request to fix that issue in the lib: https://github.com/SimonJF/IdrisNet2/pull/11

Related

Cannot interpolate trying to emulate EXPORT_OK Tag

I cannot interpolate ::GLOBAL::EXPORT($var)::. What am I doing wrong?
I'm trying to play with exports because they are hard to optimize sometimes.
I try to produce tags for a group of constants.
In reality a few constants are in visible in module scope, but some of them are in a TAG just to separate them and to use them on demand.
But the objective of my question is just to understand why I cannot interpolate what should seem to be very easy.
The error is an exception with new; I've lost the trace for now.
See the code below.
unit module TestImports;
sub bar is export { say "bar sub" }
sub baz is export { say "baz sub" }
my $var = 'He heu hey';
my $aar = 'He heu hey';
my $vaa = 'He heu hey';
my $kar = 'He heu hey';
my $vor = 'He heu hey';
constant A = 333;
constant APPART is export(:AP) = 174;
constant COLOR_A = 24;
constant COLOR_B = 84;
constant COLOR_C = 88;
constant COLOR_D = 92;
constant COLOR_E is export(:SPECIAL)= 144;
constant COLOR_F = 98;
constant COLOR_G = 118;
constant COLOR_H = 214;
constant COLOR_I = 800;
my package EXPORT::MYTAG {
#filter the colors;
my %c = TestImports::.grep(*.key.match(/^ ( COLOR_ <[A..Z]>+ ) $ /));
#filter allready in TAG exported : so we exclude those that we do not want.
my %e = EXPORT::.grep( *.key.grep( none /^ : ( ALL || DEFAULT || MYTAG ) $ /));
#This nearly works but will fail for :SPECIAL Tag because it's yet exported :(
for %c {
next if .key eq 'EXPORT';
.key.say;
OUR::{.key} := .value;
}
#NOTE: So we must exclude, :SPECIAL (and ev. others) building a loop with e.
#IF i did well red the doc ALL SPECIAL should be in GLOBAL::EXPORT::SPECIAL::%(kv);
#and
::GLOBAL::EXPORT::SPECIAL::.raku.say => WORKS; ==> (COLOR_E(80)) SO:
for %e.kv -> $k,$v {
#HERE IS THE QUESTION!!!!!!
::GLOBAL::EXPORT::($k)::.raku.say; #SHOULD WORK but does not: WHY.
}
}
Main script just for testing is this one.
#!/bin/env raku
use TestImports :DEFAULT, :MYTAG :AP ;
#Most of the time : Everything works!but it should work always
say TOTITOTO;
say INTER;
say WANDER;
say WANDER_FULL;
say WANDER3FULL;
say APPART;
say TestImports::A;
#say COLOR_INTER;
bar();
baz();
Thing.new.foo;
This answer is barely an answer, but then your question is barely a question, so perhaps it all balances out. ;)
Cannot interpolate trying to emulate EXPORT_OK Tag
I googled "EXPORT_OK". It's Perl. Simple forms of it seem simple. Why aren't you just sticking with simple tagging?
I cannot interpolate ::GLOBAL::EXPORT($var)::
There's no such package as GLOBAL::EXPORT. The EXPORT generated by Rakudo is a lexical package (declared with my) not a global package (declared with our). Your EXPORT::MYTAG package is explicitly declared with my.
::GLOBAL::EXPORT($var) attempts to call a package as if it were a function which won't work either. But that's presumably just a typo.
At a guess you meant EXPORT::($var) or something like that.
I don't know what you really want because your code doesn't compile and is too long and messy.
I'm trying to play with exports because they are hard to optimize sometimes.
If you mean Perl exports, Raku isn't Perl.
If you mean Raku exports, and mean performance, then please share your --profile results. If you mean some other aspect of optimizing, then please clarify what that is.
In reality a few constants are in visible in module scope, but some of them, are in a TAG just to separate them and to use them on demand.
The constant declarator has an implicit our declarator by default. If you don't want that, put my in front, i.e. my constant ....
But the objective of my question is just to understand wy i cannot interpolate what should seam to be very easy.
If the above hasn't answered your question, please produce a much shorter and cleaner version of your question and then we might be able to help.
The error is an exception with new, i'v lost the trace for now.
The error I see in your deleted "answer" is:
Failure.new(exception => X::NoSuchSymbol.new(symbol => "GLOBAL::EXPORT::SPECIAL"))
That's a Failure value (which is an error value containing an unthrown exception that allows code to continue to run provided nothing tries to use the error value as if it were OK).
It says there's no such symbol (NoSuchSymbol) as GLOBAL::EXPORT::SPECIAL. That's correct, because there is no such symbol/package, as explained near the start of this answer.
I see this in your comments under your deleted "answer":
I think the example is too long
Yes. I'm pretty sure that, whatever it is that you're trying to ask, it should be askable in less than 10 lines of code. See Minimal Reproducible Example for further guidance on how best to ask a question.
But I suspect the primary problem is more basic than that.
If you are experiencing problems with Raku exporting, then it seems likely that you're just using it incorrectly.
If you are using it correctly, then the first thing to do, before thinking about trying to optimize anything, is to use --profile in accord with Knuth's dictum that "Premature optimization is the root of all evil" and share your results.

Why can't you use a object property as an index in a for loop? (MATLAB)

Below is an example that doesn't work in Matlab because obj.yo is used as the for loop's index. You can just convert this to the equivalent while loop and it works fine, so why won't Matlab let this code run?
classdef iter_test
properties
yo = 1;
end
methods
function obj = iter_test
end
function run(obj)
for obj.yo = 1:10
disp('yo');
end
end
end
end
Foreword: You shouldn't expect too much from Matlab's oop capabilities. Even though things have gotten better with matlab > 2008a, compared to a real programming language, oop support in Matlab is very poor.
From my experience, Mathworks is trying to protect the user as much as possible from doing mistakes. This sometimes also means that they are restricting the possibilities.
Looking at your example I believe that exactly the same is happening.
Possible Answer: Since Matlab doesn't have any explicit typing (variables / parameters are getting typed on the fly), your code might run into problems. Imagine:
$ a = iter_test()
% a.yo is set to 1
% let's overwrite 'yo'
$ a.yo = struct('somefield', [], 'second_field', []);
% a.yo is now a struct
The following code will therefore fail:
$ for a.yo
disp('hey');
end
I bet that if matlab would support typing of parameters / variables, your code would work just fine. However, since you can assign a completely different data type to a parameter / variable after initialization, the compiler doesn't allow you to do what you want to do because you might run into trouble.
From help
"properties are like fields of a struct object."
Hence, you can use a property to read/write to it. But not use it as variable like you are trying to do. When you write
for obj.yo = 1:10
disp('yo');
end
then obj.yo is being used as a variable, not a field name.
compare to actual struct usage to make it more clear:
EDU>> s = struct('id',10)
for s.id=1:10
disp('hi')
end
s =
id: 10
??? for s.id=1:10
|
Error: Unexpected MATLAB operator.
However, one can 'set' the struct field to new value
EDU>> s.id=4
s =
id: 4
compare the above error to what you got:
??? Error using ==> iter_test
Error: File: iter_test.m Line: 9 Column: 20
Unexpected MATLAB operator.
Therefore, I do not think what you are trying to do is possible.
The error is
??? Error: File: iter_test.m Line: 9 Column: 20
Unexpected MATLAB operator.
Means that the MATLAB parser doesn't understand it. I'll leave it to you to decide whether it's a bug or deliberate. Raise it with TMW Technical Support.
EDIT: This also occurs for all other kinds of subscripting:
The following all fail to parse:
a = [0 1];
for a(1) = 1:10, end
a = {0 1};
for a{1} = 1:10, end
a = struct('a', 0, 'b', 0);
for a.a = 1:10, end
It's an issue with the MATLAB parser. Raise it with Mathworks.

function that returns value from dlsym()?

Stupid question that I'm sure is some bit of syntax that's not right. How do I get dlsym to work with a function that returns a value? I'm getting the error 'invalid conversion of void* to LSError (*)()' in the following code - trying to get the compile the linux lightscribe sample program hoping that I can link it against the OSX dylib (why the hell won't HP release an actual Cocoa SDK? LS has only been around for what? 6 or 7 years now?):
void* LSHandle = dlopen("liblightscribe.1.dylib", RTLD_LOCAL|RTLD_LAZY);
if (LSHandle) {
LSError (*LS_DiscPrinter_ReleaseExclusiveUse)() = dlsym(LSHandle, "LS_DiscPrinter_ReleaseExclusiveUse");
..
lsError = LS_DiscPrinter_ReleaseExclusiveUse( pDiscPrinter);
The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.
The “recommended” way to use dlsym is:
LSError (*LS_DiscPrinter_ReleaseExclusiveUse)(LS_DiscPrinterHandle);
*(void **)&LS_DiscPrinter_ReleaseExclusiveUse = dlsym("LS_DiscPrinter_ReleaseExclusiveUse");
Read the rationale and example on the POSIX page for dlsym for more information.

Generating a list of lists of Int with QuickCheck

I'm working through Real World
Haskell one of the
exercises of chapter 4 is to implement an foldr based version of
concat. I thought this would be a great candidate for testing with
QuickCheck since there is an existing implementation to validate my
results. This however requires me to define an instance of the
Arbitrary typeclass that can generate arbitrary [[Int]]. So far I have
been unable to figure out how to do this. My first attempt was:
module FoldExcercises_Test
where
import Test.QuickCheck
import Test.QuickCheck.Batch
import FoldExcercises
prop_concat xs =
concat xs == fconcat xs
where types = xs ::[[Int]]
options = TestOptions { no_of_tests = 200
, length_of_tests = 1
, debug_tests = True }
allChecks = [
run (prop_concat)
]
main = do
runTests "simple" options allChecks
This results in no tests being performed. Looking at various bits and
pieces I guessed that an Arbitrary instance declaration was needed and
added
instance Arbitrary a => Arbitrary [[a]] where
arbitrary = sized arb'
where arb' n = vector n (arbitrary :: Gen a)
This resulted in ghci complaining that my instance declaration was
invalid and that adding -XFlexibleInstances might solve my problem.
Adding the {-# OPTIONS_GHC -XFlexibleInstances #-} directive
results in a type mismatch and an overlapping instances warning.
So my question is what's needed to make this work? I'm obviously new
to Haskell and am not finding any resources that help me out.
Any pointers are much appreciated.
Edit
It appears I was misguided by QuickCheck's output when in a test first manner fconcat is defined as
fconcat = undefined
Actually implementing the function correctly indeed gives the expected result. DOOP!
[[Int]] is already an Arbitrary instance (because Int is an Arbitrary instance, so is [a] for all as that are themselves instances of Arbitrary). So that is not the problem.
I ran your code myself (replacing import FoldExcercises with fconcat = concat) and it ran 200 tests as I would have expected, so I am mystified as to why it doesn't do it for you. But you do NOT need to add an Arbitrary instance.

Calling functions from within function(float *VeryBigArray,long SizeofArray) from within objC method fails with EXC_BAD_ACCESS

Ok I finally found the problem. It was inside the C function(CarbonTuner2) not the objC method. I was creating inside the function an array of the same size as the file size so if the filesize was big it created a really big array and my guess is that when I called another function from there, the local variables were put on the stack which created the EXC_BAD_ACCESS. What I did then is instead of using a variable to declare to size of the array I put the number directly. Then the code didnt even compile. it knew. The error wassomething like: Array size too big. I guess working 20+hours in a row isnt good XD But I am definitly gonna look into tools other than step by step debuggin to figure these ones out. Thanks for your help. Here is the code. If you divide gFileByteCount by 2 you dont get the error anymore:
// ConverterController.h
# import <Cocoa/Cocoa.h>
# import "Converter.h"
#interface ConverterController : NSObject {
UInt64 gFileByteCount ;
}
-(IBAction)ProcessFile:(id)sender;
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp);
#end
// ConverterController.m
# include "ConverterController.h"
#implementation ConverterController
-(IBAction)ProcessFile:(id)sender{
UInt32 packets = gTotalPacketCount;//alloc a buffer of memory to hold the data read from disk.
gFileByteCount=250000;
long LENGTH=(long)gFileByteCount;
CarbonTuner2(LENGTH,(long)8192/2, (long)4*2);
}
#end
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp)
{
long numFrames = numSampsToProcess / fftFrameSize * osamp;
float g2DFFTworksp[numFrames+2][2 * fftFrameSize];
double hello=sin(2.345);
}
Your crash has nothing to do with incompatibilities between C and ObjC.
And as previous posters said, you don't need to include math.h.
Run your code under gdb, and see where the crash happens by using backtrace.
Are you sure you're not sending bad arguments to the math functions?
E.g. this causes BAD_ACCESS:
double t = cos(*(double *)NULL);
Objective C is built directly on C, and the C underpinnings can and do work.
For an example of using math.h and parts of standard library from within an Objective C module, see:
http://en.wikibooks.org/wiki/Objective-C_Programming/syntax
There are other examples around.
Some care is needed around passing the variables around; use the C variables for the C and standard library calls; don't mix the C data types and Objective C data types incautiously. You'll usually want a conversion here.
If that is not the case, then please consider posting the code involved, and the error(s) you are receiving.
And with all respect due to Mr Hellman's response, I've hit errors when I don't have the header files included; I prefer to include the headers. But then, I tend to dial the compiler diagnostics up a couple of notches, too.
For what it's worth, I don't include math.h in my Cocoa app but have no problem using math functions (in C).
For example, I use atan() and don't get compiler errors, or run time errors.
Can you try this without including math.h at all?
First, you should add your code to your question, rather than posting it as an answer, so people can see what you're asking about. Second, you've got all sorts of weird problems with your memory management here - gFileByteCount is used to size a bunch of buffers, but it's set to zero, and doesn't appear to get re-set anywhere.
err = AudioFileReadPackets (fileID,
false, &bytesReturned, NULL,0,
&packets,(Byte *)rawAudio);
So, at this point, you pass a zero-sized buffer to AudioFileReadPackets, which prompty overruns the heap, corrupting the value of who knows what other variables...
fRawAudio =
malloc(gFileByteCount/(BITS/8)*sizeof(fRawAudio));
Here's another, minor error - you want sizeof(*fRawAudio) here, since you're trying to allocate an array of floats, not an array of float pointers. Fortunately, those entities are the same size, so it doesn't matter.
You should probably start with some example code that you know works (SpeakHere?), and modify it. I suspect there are other similar problems in the code yoou posted, but I don't have time to find them right now. At least get the rawAudio buffer appropriately-sized and use the values returned from AudioFileReadPackets appropriately.