code logs -> 2008 -> Sat, 06 Sep 2008< code.20080905.log - code.20080907.log >
--- Log opened Sat Sep 06 00:00:03 2008
00:09
<@McMartin>
Hmm. Is there a decent Windows equivalent to ldd or otool?
00:09
<@McMartin>
It would be nice to statically trace DLL references.
00:09
<@McMartin>
And it would also be nice if it actually worked on DLLs too
00:10
<@ToxicFrog>
Cygwin comes with a version of nm that supports PEs, but that traces individual imports, not DSO linkages
00:10
<@ToxicFrog>
I know that such a tool exists, because I've seen it mentioned, but I don't remember what it's called.
00:10
<@ToxicFrog>
although in a pinch I've found that strings foo | fgrep -i .dll works~
00:13 * McMartin is kind of tired of migrating library-heavy applications over by running it and reading off the errors on failed loads.
00:13
<@McMartin>
Though I do at least only have to do this once.
00:13
<@McMartin>
(Not that I'm objecting, since it means that suites of applications can be compactly aggregated)
00:13
<@ToxicFrog>
Yeah, I just use the strings approach
00:14
<@McMartin>
And at runtime, Process Explorer 4tw
00:14
<@McMartin>
Which is nice because it works even when they're doing Reflection, C Style.
00:14
<@ToxicFrog>
If all else fails, the PE format isn't all that nasty, you could hack together one of your own.
00:14
<@McMartin>
That's more work than just grabbing everything built.
00:14
<@ToxicFrog>
True.
00:15
<@McMartin>
(My latest experiments with VBox require a custom build.)
00:15
<@McMartin>
So actually, the other question is thus "OK, I changed this source file, which DLL changed, and the question's even poorly phrased because there's some duplication. ;_;
00:15
<@McMartin>
So yeah, copying everything to make sure, I think.
00:17
<@McMartin>
But it would still be nice to have.
00:18 * McMartin flails at apt
00:18
<@McMartin>
WHY ARE THE MAN PAGES NOT PART OF THE GCC PACKAGE
00:18
<@ToxicFrog>
Isn't answering "which DLL changed if I changed this source" done by "make && ls -ltrah"?
00:18 * ToxicFrog joins in the flailing
00:18
<@ToxicFrog>
man pages in ubuntu/debian are the bane of my existence.
00:18
<@McMartin>
VBox uses a custom builder that touches all the final products. ;_;
00:18
<@McMartin>
Do you happen to know what the package is for the man pages?
00:19
<@ToxicFrog>
Not anymore ;.;
00:19
<@McMartin>
(Seriously, stuff like this is exactly why I prefer Fedora, and probably would even if yum were 10 times worse)
00:19
<@ToxicFrog>
Are you looking for the glibc man pages, or the gcc man pages?
00:19
<@McMartin>
I want strncpy's calling convention and friends.
00:19
<@ToxicFrog>
libc, then.
00:20
<@McMartin>
Specifically its many friends, because I've forgotten whether or not strnlen exists or is standard.
00:20
<@ToxicFrog>
ISTR apt having a "what package contains this file" command?
00:20
<@ToxicFrog>
You could ask what provides */man3/strlen.3, say
00:21
<@McMartin>
Oh, hey, "suggested packages" with g++
00:21
<@ToxicFrog>
Also, according to my man pages, strnlen exists, but is not standard; it's a _GNU_SOURCE extension.
00:21
<@McMartin>
gcc-4.2-doc glibc-doc manpages-dev
00:21
<@ToxicFrog>
(callconvs: strnlen(const char *, size_t), strncpy(char *, const char *, size_t)
00:22
<@McMartin>
It may be nonstandard, but both GNU and MSVC support it.
00:22
<@McMartin>
Good enough for me.
00:22
<@ToxicFrog>
Is it just me, or is there something about the str* and strn* functions that makes their callconvs fucking impossible to remember?
00:23
<@McMartin>
Yes.
00:23
<@McMartin>
It's that the n is never anywhere consistent.
00:23
<@McMartin>
It's at the end except when it's at the beginning except when it's the second argument.
00:24 Thaqui [~Thaqui@121.98.137.ns-13370] has left #code [He was a wise man who invented beer - Plato]
00:31
<@McMartin>
Mm. strnlen isn't supported by enough of MSVC.
00:32 * McMartin shall have to write a for loop by hand, alas. =P
00:37
<@gnolam>
MSVC's C string handling functions are full of epic fail. :P
00:39
<@McMartin>
I refuse to fault them for not violating the standard in the same was as GNU for as long.
00:55
<@gnolam>
strnlen() I don't fault them for. But snprintf()? How long did it take them to incorporate that?
00:55
<@gnolam>
(If indeed they have. I haven't checked.)
00:56
<@ToxicFrog>
Also, providing extra stuff isn't a violation of the standard unless the standard specifically says not to include extra stuff.
00:56
<@ToxicFrog>
And if it does say that, they had better have a really impressive justification for it.
01:05
<@gnolam>
And in other news, http://www.chiptune.com is jaw-droppingly awesome.
01:15
<@ToxicFrog>
The domain name fills me with anticipation but the site itself is total ####.
01:16
<@ToxicFrog>
Hey, let's combine a mystery meat menu with shitty browser-killing javascript tricks!
01:20
<@ToxicFrog>
Ok, this site is completely unusable.
01:20
<@ToxicFrog>
wtb plain html version pst
02:25
<@McMartin>
gnolam: snprintf has been vaguely available since at least VC6, though ISTR you needed a Windows-specific header.
02:27
<@McMartin>
Most of the Post-C89 library additions have been in MSVC for a good while, just with underscores in front.
02:27
<@McMartin>
(VC6 was what, '98? '99?)
03:10
<@gnolam>
Forcing you to #ifdef MSVC_VER ... == epic fail.
03:12
<@gnolam>
Anyway. Sleep.
03:12
<@gnolam>
I hear humans need that.
03:12 gnolam [lenin@Nightstar-1382.A163.priv.bahnhof.se] has quit [Quit: Z?]
03:30
<@McMartin>
Average size of a compiler.h in 1991: 7,000 lines.
03:30
<@McMartin>
Average size now: Maybe a dozen.
03:30
<@McMartin>
Totally not epic.
03:31
<@McMartin>
Especially since you need to #ifdef it anyway for many, many system-specific things that aren't even part of the language.
03:32
<@Vornicus>
I need a syntax-highlighting editor for Windows with a Javascript mode that can be stuffed on a USB drive.
03:32
<@McMartin>
And yeah, it looks like most of the C99 functions were in MSVC from 2005 on.
03:32
<@McMartin>
Under their names
03:32
<@McMartin>
Just in time for ISO to decide "oh wait, we're going to make them all have underscores in front now because they aren't the C++ standard library."
03:32
<@Vornicus>
kill.
03:33
<@McMartin>
Well, they're already std::printf and all.
03:33
<@McMartin>
There are nonstandard conventions with headers to have them auto-import.
03:33
< GeekSoldier>
Vorn: eclipse?
03:34
<@Vornicus>
GS: yeesh, going straight for the big guns, are we.
03:34
< GeekSoldier>
it's what I'm familiar and comfortable with.
03:34
<@Vornicus>
Wiat, it does Javascript?
03:34
< GeekSoldier>
yep.
03:34
<@McMartin>
Notepad++ doesn't fit on a USB drive?
03:35
<@McMartin>
Hm. I suspect it does.
03:35
<@McMartin>
I suggest Notepad++.
03:36
< GeekSoldier>
notepad++ runs standalone?
03:36
<@McMartin>
Define "standalone".
03:36 * GeekSoldier is thoroughly unfamiliar with the program.
03:36
< GeekSoldier>
no need to install anything to a 'local' drive.
03:36
< GeekSoldier>
gar... alcohol and brain don't mix well. sorry.
03:37
< Consul>
It does have an installer, but that installer can target a flash drive.
03:37
<@McMartin>
http://notepad-plus.sourceforge.net/uk/site.htm
03:37
< Consul>
(I use Notepad++ when I'm on Windows)
03:37
<@McMartin>
There's a zip-format installation too.
03:38
<@McMartin>
"For the zip format installation, if it's the first time you install Notepad++, just unzip the zip file to desired directory, then execute notepad++.exe"
03:38
< GeekSoldier>
heh, got it. quite useful.
03:39
<@McMartin>
However, I don't know if it still touches the registry etc
03:40
<@McMartin>
Anyway, time to go home.
03:40
< GeekSoldier>
thanks,McM.
03:40
< GeekSoldier>
enjoy!
04:22 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has quit [Ping Timeout]
04:22 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has joined #code
04:37 Thaqui [~Thaqui@Nightstar-12187.worldnet.co.nz] has joined #code
04:37 mode/#code [+o Thaqui] by ChanServ
05:00 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has quit [Killed (NickServ (GHOST command used by C_tiger_))]
05:01 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has joined #code
05:05 crem [~moo@Nightstar-28703.adsl.mgts.by] has quit [Quit: Ep0xa 1.2v]
05:15 crem [~moo@Nightstar-28703.adsl.mgts.by] has joined #code
05:16 Thaqui [~Thaqui@Nightstar-12187.worldnet.co.nz] has left #code [He was a wise man who invented beer - Plato]
06:28 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has quit [Killed (NickServ (GHOST command used by C_tiger_))]
06:28 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has joined #code
07:06 AnnoDomini [AnnoDomini@Nightstar-29194.neoplus.adsl.tpnet.pl] has joined #Code
07:06 mode/#code [+o AnnoDomini] by ChanServ
07:29 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has quit [Killed (NickServ (GHOST command used by C_tiger_))]
07:29 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has joined #code
07:32 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has quit [Ping Timeout]
07:32 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has joined #code
09:18 You're now known as TheWatcher
10:36 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has quit [Killed (NickServ (GHOST command used by C_tiger_))]
10:36 C_tiger [~c_wyz@Nightstar-4230.hsd1.ca.comcast.net] has joined #code
11:50 Consul [~darren@Nightstar-1439.dsl.sfldmi.ameritech.net] has quit [Operation timed out]
12:03 Consul [~darren@Nightstar-1439.dsl.sfldmi.ameritech.net] has joined #code
12:48 gnolam [lenin@Nightstar-1382.A163.priv.bahnhof.se] has joined #Code
12:48 mode/#code [+o gnolam] by ChanServ
17:04 * gnolam stabs Emacs' syntax highlighting with a hand-and-a-half shiv.
17:11
< Shoukanjuu>
Where did that come from? Hand-and-a-half?
17:12
<@ToxicFrog>
Hand-and-a-half sword, aka bastard sword. Bigger than a one-handed longsword but smaller than a two-handed greatsword.
17:12
< Shoukanjuu>
That's what I thought.
17:13
< Shoukanjuu>
Syntax highlighting, you say? >.>
17:14 * Reiver burns TF with D&D anachronysms.
17:15
<@Reiver>
A 'longsword' was, in fact, a hand-and-half weapon from the 14th century. Bastard swords were actually a slightly shorter version, and the contemporary one-hander was a sidesword. In earlier times, it was primarily known as a 'sword'.
17:15
<@Reiver>
(Yes, the old languages are just as bad as modern ones for overloading their nouns~)
17:15
< GeekSoldier>
heh.
17:15
<@Reiver>
</nitpick>
17:25
< Shoukanjuu>
Tidal wave+Overlimit=infinitecombo
17:25
<@gnolam>
And then along came the Victorians and fubared the terminology for all time.
17:26
< Shoukanjuu>
\o/
17:26
< Shoukanjuu>
Well, since fubar means what it means
17:26
< Shoukanjuu>
Wouldn't saying 'for all time' be rather...redundant? >>
17:27
<@gnolam>
Depends on if you interpret the last 'R' as "repair" or "recognition".
17:28
< Shoukanjuu>
I see. I've only used it as repair, so naturally, I thought that at first.
17:29
<@Reiver>
gnolam: Not even really the victorians. It's largely D&D, which was just about as bad. :p
17:33
< Shoukanjuu>
Eh, blades are fun and all
17:33
< Shoukanjuu>
But when you're as good a shot as me, it's just a waste >.>
17:34
<@Reiver>
On the contrary, blades make for an excelent form of fitness. ;)
17:34
<@Reiver>
With added bonus of a self-defense form that actually has explicit training in how to deal with armed attackers while unarmed, because that's the fundamental assumption of your wrestling techniques >_>
17:35
<@Reiver>
(AKA: You lost your sword, and are now attempting to disarm/break joints of the other bugger before he can take advantage of this fact~)
17:35
< Shoukanjuu>
Fitness, indeed
17:36
<@Reiver>
(...Not that you'd want to try it. In a real fight, there's still a real chance of getting horribly injured or killed, afterall... but it's still mildly comforting that you know more than you would have, say, jogging. :p)
17:37
< Shoukanjuu>
Of course.
17:37
< Shoukanjuu>
I learned how to fight by getting into fights
17:37 * Reiver did that too, though the opponents weren't armed thank heavens.
17:38
< Shoukanjuu>
Fighting isn't about beating oyur opponent, it's about knowing WHEN to try, and when NOT to
17:39
< Shoukanjuu>
Chances are, if they are armed with anything more than a gun...They really don't know how to "use" it
17:39
< Shoukanjuu>
Of course, you can TRY to disarm them, or you can...well, not risk it
17:40
< Shoukanjuu>
Most people who are armed don't want to stab someone, they just do it in case you'd get scared and do what they want
17:40
< Shoukanjuu>
If they intended to use it, they would have
17:42
< Shoukanjuu>
Stabbing hurts. :(
17:50
< Shoukanjuu>
Sometimes it might be worth it, but you're gambling with something that you shouldn't be, when you're in that position
18:34
<@ToxicFrog>
I am amused by the "post your most horrible design decisions" thread on SA.
18:35
<@ToxicFrog>
"I think the worst one was writing an IRC bot and just shoveling the new features on top of the old features without overhauling anything, to the point where the bot was sending itself PMs to communicate between feature sets. <picture of a smiley face shooting itself>"
18:35
<@ToxicFrog>
'I can't count the number of times I've said "this is such a small app, I'll just use flat files instead of a database."'
18:36
<@ToxicFrog>
"Someday, I'll stop trying to emulate Curses using Swing"
18:38 * Vornicus sends /that/ one to Toady.
20:08 ToxicFrog [~ToxicFrog@Admin.Nightstar.Net] has quit [Operation timed out]
20:12 ToxicFrog [~ToxicFrog@Admin.Nightstar.Net] has joined #code
20:12 mode/#code [+o ToxicFrog] by ChanServ
21:53 Thaqui [~Thaqui@121.98.137.ns-13370] has joined #code
21:53 mode/#code [+o Thaqui] by ChanServ
22:28 androsch [~androsch@Nightstar-3933.pools.arcor-ip.net] has joined #code
22:31
< Consul>
Okay, I have a C++ multiple inheritance question for y'all...
22:31
<@MyCatVerbs>
Don't?
22:31
< Consul>
How about I ask my question?
22:31
<@MyCatVerbs>
I mean, that sentence already has "C++" and "multiple inheritance" in it. This can't end well.
22:32
< Consul>
Fine, I'll go elsewhere, then. Thanks!
22:32
<@MyCatVerbs>
I mean "don't multiply inherit" and "don't hack in C++", not "don't ask". :)
22:32
<@MyCatVerbs>
Nooooooooo!
22:32
<@MyCatVerbs>
Come back! I was only (half-)joking. We'll, uh, give you a cookie?
22:58
<@ToxicFrog>
Consul: first of all, don't ask to ask, just ask.
22:59
<@ToxicFrog>
Second of all, multiple inheritance is not just full of but made of spiders and should be avoided if at all possible.
22:59
<@MyCatVerbs>
ToxicFrog: IMO, inheritance in general is spidery.
23:00
<@ToxicFrog>
Inheritance is very nice, the problem is that it gets used a lot when people should be using composition.
23:00
<@MyCatVerbs>
ToxicFrog: but then I've only ever worked with tree-inheritance languages like Java, Python and company. Perhaps my opinion would be different if I was using prototype-based OO? Anyway.
23:00
<@ToxicFrog>
Easy way to find out: roll your own and see if you like it more.
23:01
<@MyCatVerbs>
ToxicFrog: I get the impression that inheritance isn't particularly useful if you have either a duck-typeable messaging convention or something like Java interfaces.
23:02
<@MyCatVerbs>
If you have either of those, then you can simulate the effect of inheritance by composition and writing some boilerplate that delegates to the inner object. Wordy, but more flexible.
23:04
<@MyCatVerbs>
All inheritance gets you over those is that it automatically sorts the delegation out for you, for all the methods that you don't override - but it's only really good at doing so with exactly one parent class, because otherwise you can have ambiguities as to which of the parent methods should be used in a particular situation if several overlap.
23:04
<@ToxicFrog>
Correct.
23:05
<@ToxicFrog>
Basically what you are saying is "inheritance is useful but not all the time"
23:05
<@ToxicFrog>
Which is pretty much my stance on it, so
23:05
<@MyCatVerbs>
Whereas abusing composition+(interfaces|smalltalk-ish-messaging) lets you arrange the delegation graph in arbitrarily screwy (and useful) ways without ever having any ambiguity whatsoever.
23:05
< Consul>
Never mind. I already know that what I had in mind won't work.
23:08
<@MyCatVerbs>
ToxicFrog: yeah, but I can't think of so many examples where it actually *is* useful. I get the impression that interfaces or typeclasses (for the statically-typed crowd) and duck-typing are more useful in such a proportion of cases that maybe it isn't actually worth having an inheritance mechanism.
23:08
<@MyCatVerbs>
s/more useful/what you really want/
23:09
<@MyCatVerbs>
ToxicFrog: doubly so because all the OO weenies these days claim that inheritance is for polymorphism, not code reuse.
23:09
<@MyCatVerbs>
Only caveat is that I've yet to try anything Self-like (like, say, Javascript - probably a dire omission on my part).
23:09
<@ToxicFrog>
I actually consider typeclasses to be a form of inheritance, at least the way Haskell does them
23:10
<@MyCatVerbs>
s/Only c/C/
23:10
< Consul>
There has to be a way I can create a library of functions in a namespace that won't require objects to be made.
23:10
<@ToxicFrog>
Consul: static member functions? Skip classes entirely and just write the functions directly?
23:10
<@ToxicFrog>
Either of those will work.
23:10
<@MyCatVerbs>
ToxicFrog: they're polymorphism, yes, but not inheritance. There's no mechanism for implicitly delegating to a superclass.
23:10
< Consul>
ToxicFrog: In an external file that's easily included?
23:10
<@ToxicFrog>
MyCatVerbs: except that you have, say, Eq. And then you define Ord, which is_a Eq. And then Num is_a Ord...
23:10
< Consul>
And see, that still won't work...
23:11
< Consul>
How can I explain this without needing pages and pages...
23:11
< Consul>
DSP is a complicated problem space.
23:11
<@MyCatVerbs>
ToxicFrog: yyyyyess, point.
23:11
<@ToxicFrog>
Consul: well, you said "library", so presumably it would be header with prototypes + object code, but you could also do it as a single header, I think
23:11
<@ToxicFrog>
Since C++ is much more forgiving of multiple identical declarations than C is
23:12
< Consul>
That still doesn't work, and I'm trying to figure out how to explain why...
23:12
<@ToxicFrog>
But statics, or naked functions + the namespace keyword, are the typical approaches
23:12
<@MyCatVerbs>
That's more along the lines of asserting "it's always possible to judge equality on types that you can judge ordering on" than anything Simula-style OO gets you. There's never any implicit delegation.
23:13
< Consul>
Okay, let me see if I can give an example...
23:14
< Consul>
At a base level, we have a single-sample delay line.
23:14
< Consul>
That single-sample delay line is then used to make a bilinear integrator...
23:14
<@ToxicFrog>
MyCatVerbs: but it will fall back to the default implementations given for operations on Eq
23:14
<@ToxicFrog>
Likewise for Ord
23:14
< Consul>
Which can then be used to create filters...
23:14
<@MyCatVerbs>
ToxicFrog: please elaborate? I'm not quite following you there.
23:14
< Consul>
So, three layers of functions.
23:15
<@MyCatVerbs>
ToxicFrog: there's a deriving mechanism for Eq, and another for Ord, but those are an entirely different matter.
23:15
<@ToxicFrog>
MyCatVerbs: you can provide default implementations for operations in a typeclass. Eg, in Ord, you can provide a default implemtation for >=.
23:15
<@ToxicFrog>
Types within that TC can provide their own, but if they don't the default will be used.
23:15
<@ToxicFrog>
Similarly, if something is Num, and doesn't provide its own >=, it'll fall back to the one provided by the 'superclass', Ord
23:15
< Consul>
Now, there is also a base function for helping a DSP processor act as a node in a directed graph...
23:16
<@ToxicFrog>
You are correct that there's no equivalent to the super keyword, though
23:16
< Consul>
So...
23:16
<@McMartin>
Consul: Are these functions, essentially, "first-class"?
23:16
<@McMartin>
I will explain...
23:16
< Consul>
The final filter inherits from both the DSP side and the Node side.
23:16
<@McMartin>
A first-class function is essentially one that gets used as if it were a variable; you're passing it around, using it to build other more complex functions, etc.
23:17
< Consul>
McMartin: Exactly! Just like in functional languages.
23:17
<@McMartin>
OK.
23:17
<@McMartin>
OK. How good are you at functional languages?
23:17
<@McMartin>
THe answer is either "it's trivial" or "it's impossible" depending on a specific test.
23:17
< Consul>
I can work my way around Faust pretty good. I never studied any more general purpose ones.
23:17
<@McMartin>
(Well, impossible without using objects.)
23:17
<@McMartin>
Hrm.
23:17
<@MyCatVerbs>
ToxicFrog: the defaulting is something else again. It's just a convenience for when you have several member functions that can be defined in terms of one another.
23:18
<@McMartin>
OK, I'm going to give the academic version first, then make a sandwich because jesus christ it's 3:30, then answer the bits that made no sense
23:18
<@McMartin>
WHich may be all of it, but
23:18
< Consul>
McMartin: My original idea was to make the delay line a class, inherited by the bilinear integrator, which is then inherited by the filter. The issue comes in, what if I'm making something using the integrator, then I tell my class to inherit from the delay line...
23:19
<@McMartin>
Is the function totally self-contained - that is, was it defined at global scope in the functional language, or does it not refer outside of it? That is, Will the function be defined in terms of variables that vary in terms of each reference?
23:20
< Consul>
Yes, these would be totally self-contained functions.
23:20
<@McMartin>
So, there's a buzzword called "Strategy Pattern" that is what you use for the integrator - it takes takes the delay line as a constructor argument, but whether that can be a function pointer or if it has to be an object depends on whether or not you'd be playing scope games in LISP
23:20
<@McMartin>
OK, so, if there'd be no locals
23:20
<@McMartin>
You can just say, for instance
23:20
<@McMartin>
int filter(int x) { ... }
23:20
<@McMartin>
BiLinInt makeBiLinInt (int (*f)(int), ....) { ... }
23:21
<@McMartin>
And then f is a function pointer taking and returning int
23:21
<@McMartin>
Which you can call like any other
23:21
<@McMartin>
The OO-ier way of doing it is to have a filter class with one method and pass that in.
23:21
<@McMartin>
The advantage of that is that it means that you can play the make-adder trick.
23:21
< Consul>
I'm not sure I follow. I think it would be the other way around, the bilinear integrator gets used by the filter.
23:22
< Consul>
But besides, that silly nitpick at this stage...
23:22
<@McMartin>
15:19 < Consul> At a base level, we have a single-sample delay line.
23:22
<@McMartin>
15:19 < Consul> That single-sample delay line is then used to make a bilinear integrator...
23:22
<@McMartin>
Did I misunderstand what "is then used" means here?
23:22
<@McMartin>
I thought that meant "as a component of the integrator's algorith"
23:22
<@McMartin>
algorithm, rather
23:22
< Consul>
Yes
23:23
< Consul>
I think I just misunderstood something you said.
23:23
<@McMartin>
Right. No inheritance relation, classically
23:23
<@McMartin>
For the OO version (because Java doesn't *have* function pointers), look up their ordered sets, which take a Comparator object as a constructor argument but don't inherit from Comparator themselves
23:25
<@MyCatVerbs>
ToxicFrog: there is http://homepages.cwi.nl/~ralf/OOHaskell/ , but I don't think it's idiomatic to use the language that way very much. More like using Haskell to emulate OO style than actually applying Haskell's strengths, rather than its weaknesses.
23:26
<@McMartin>
So it's "I have <<a comparison function>>, I'm going to use it to make <<a sorting algorithm>>, which will then become part of <<an implementation of a list that's always in order>>."
23:26
<@McMartin>
And the stuff in <<>> sounds like it swaps out.
23:26
<@McMartin>
Do I understand right?
23:27
< Consul>
I don't really know. Think of it like an electronic circuit, maybe? I need parts A and B to make subassembly C which then makes assembly D.
23:27
<@McMartin>
Hm.
23:27
<@McMartin>
Yeah, that pretty much cries out "composition"
23:28
<@McMartin>
C has an A and a B in it, and D has a C in it.
23:28
< Consul>
But it would be really nice if I didn't have to instantiate objects of type A and B to make C.
23:29
<@McMartin>
So, there's two or three ways around this
23:29
< Consul>
Because I think an object would be overkill for most of these very basic parts.
23:29
<@McMartin>
(a) if there's no member variables in objects of type A and B, use function pointers
23:29
< Consul>
But they do need to be static, which I guess makes things tougher.
23:30
<@McMartin>
(b) if there's no member variables in a class, they compile down to, essentially, function pointers in the first place, so you can just trust the compiler and not worry about it
23:30
<@McMartin>
I'm not sure I follow what you mean by "static"
23:30 AnnoDomini [AnnoDomini@Nightstar-29194.neoplus.adsl.tpnet.pl] has quit [Ping Timeout]
23:30
< Consul>
Well, a delay line has to remember its state from the last time it was called.
23:30
<@McMartin>
(c) If there's no state, make one copy and share it around so you don't have to instantiate
23:30
<@McMartin>
Oh, *that* kind of static
23:31
<@McMartin>
That's a member variable, and is exactly the kind of thing you want an object for.
23:31 Vornotron [~vorn@64.252.178.ns-13935] has joined #code
23:31
<@ToxicFrog>
I love the way "static" means three different things when talking about C++
23:31
<@McMartin>
Because otherwise if you make *two* they'll be stomping on each other.
23:31
< Consul>
Hrm, I think I can see what you mean now.
23:31 Vornicus [~vorn@Admin.Nightstar.Net] has quit [Ping Timeout]
23:32
<@McMartin>
(There's a trick you can do with returning a function that you defined *inside* the function in LISP that gets you the same effect.)
23:32
<@McMartin>
(However, it's semantically kind of ambiguous everywhere else, so Python will yell at you if you try it and make you use objects instead.)
23:33
<@McMartin>
But yeah, for very small objects construction costs are pretty minimal.
23:33
< Consul>
I just want it to be easy to throw together any kind of DSP construct.
23:34
<@McMartin>
... Hmmmmmm.
23:34
<@McMartin>
These A, B, C, D things in your example
23:34
<@McMartin>
Are they all essentially black boxes to the running of the circuit?
23:35
<@McMartin>
That is, once you have some signal you want to process, you could take any of them, and have it be "out = process (in)"?
23:35
< Consul>
They could be...
23:35
<@McMartin>
Because if so, that would be a pretty awesome base class.
23:35
< Consul>
Yes, I think I would say that they are.
23:36
<@McMartin>
You could have some basic collection classes that boil down to "OK, chain this list of components together and treat it as one component", or you could do switching and that kind of thing too.
23:36
< Consul>
A single-sample delay would simply give you back the previous sample when you feed it a new one...
23:36
< Consul>
Okay, THAT's moving toward what I'd really like to do.
23:37
<@McMartin>
OK.
23:37
<@McMartin>
I'm seeing a design that looks something like this, then
23:37
<@McMartin>
TF, MCV, if you're around, vet this for me
23:37
<@McMartin>
It's a two-level inheritance hierarchy.
23:38
<@McMartin>
At the top is this class, which I will reproduce in full:
23:38 * MyCatVerbs --> brush teeth, brb.
23:38
<@McMartin>
class DSPComponent { virtual SAMPLE_TYPE process (SAMPLE_TYPE) = 0; };
23:39
<@McMartin>
All your components then inherit from this with their own implementation of "process" and their own constructors and variables and such.
23:39
<@McMartin>
So your single-sample delay would be:
23:40
<@McMartin>
(Oops. I forgot the "public:" at the top of DSPComponent)
23:40 Vornotron is now known as Vornicus
23:40
< Consul>
This is suddenly easier for me to follow now that you have me thinking in terms of what can be a black box.
23:41
<@McMartin>
class SSDelay : public DSPComponent { SAMPLE_TYPE x; public: SAMPLETYPE process(SAMPLE_TYPE in) { SAMPLE_TYPE out = x; x = in; return out; } };
23:41
<@McMartin>
And *then*, when you have your integrator, it can have "SSDelay ssd;" as a member and C++ will automatically do all the constructoring and such behind your back.
23:41
< Consul>
Sweet! I think that'll work perfectly.
23:41
<@MyCatVerbs>
That sounds pretty much like what I'd do, except that I'd stop to whine about "why can't I just use a nice ML language, dammit?" first. :)
23:41
< Consul>
Thank you!
23:42
<@McMartin>
No worries
23:42
< Consul>
The integrator can also be a black box, as it turns out.
23:42
<@McMartin>
Be warned, however, that if you start doing "Generic components" of the kind where you're passing in pieces as arguments, you *may* run into a couple of gotchas.
23:42
<@McMartin>
Yup, so the integrator would *also* inherit from DSPComponent
23:42
<@MyCatVerbs>
(Actually that's better than what I'd do. I'd use first-class functions and let the optimizer constant-fold it all into straight-line code.)
23:43
<@McMartin>
(I'm not convinced it could, because you'd have to play reference games and such)
23:44
< Consul>
And the final filter, which is our goal, would need two integrators and its own delay line.
23:44
<@McMartin>
Which you could have as member variables, if that's going to be "soldered in".
23:44
<@MyCatVerbs>
McMartin: it will. If all the functions that you're passing around are constant at compile time then it can just inline their definitions.
23:44
< Consul>
And that filter, rather than inheriting from DSPComponent, would inherit from DigraphNode instead.
23:44
<@McMartin>
Is that "two in, one out"?
23:45
< Consul>
A node can have any number of inputs and outputs. The base class will have all that stuff.
23:45
< Consul>
But a basic filter would be two in, one out, yes.
23:45
< Consul>
signal in, frequency cutoff in, signal out.
23:46
<@McMartin>
Nod.
23:46
<@McMartin>
Anyway, one last efficiency note
23:46
<@McMartin>
If you're defining these as member variables that aren't made with new(), then it actually incorporates them into the object itself
23:47
<@McMartin>
This will be faster than a standard method call.
23:47
< Consul>
So, don't use new, just treat them as variables?
23:47
<@McMartin>
(Oops, one more bug; I forgot to mark the SSDelay's version of process() as virtual)
23:47
<@McMartin>
Yeah.
23:47
<@McMartin>
With default constructors, that's as simple as...
23:47
<@McMartin>
SSDelay ssd;
23:48
<@McMartin>
With ones with arguments, you do either
23:48
<@McMartin>
AnyDelay delayer(3);
23:48
<@McMartin>
or
23:48
<@McMartin>
AnyDelay delayer = 3;
23:48
<@McMartin>
or
23:48
<@McMartin>
AnyDelay delayer = AnyDelay(3);
23:48
< Consul>
Oh, I see, for a delay that can be any fixed size.
23:48
<@McMartin>
I personally tend to use the first, but the last is probably the easiest to read.
23:49
<@McMartin>
Yeah
23:49 * Vornicus agrees with McM on both of those.
23:49
<@McMartin>
In all of these cases, you'd be calling ssd.process or delayer.process, though, not ssd->process.
23:49
< Consul>
Right...
23:49
<@McMartin>
A place where you'd need the -> version would be, say, a chain of filters, which probably has a real DSP name
23:49
< Consul>
That's actually how I learned to do it anyway. :-)
23:50
<@McMartin>
But it would be a list of DSPComponents and you'd iterate through them in turn, passing their outputs to one another
23:50
<@McMartin>
And then treating all that as a single component.
23:50
< Consul>
Curse that C++ for engineers class...
23:50
< Consul>
Oh, that's a cool idea...
23:50
< Consul>
Anyway, I need to run off to the store. I'll BBL. Thank you again!
23:51
<@McMartin>
For *that*, you'd need to pass not DSPComponents into the constructor, but pointers to them, because there's no guarantee that the Components will all be the same size.
23:51 You're now known as TheWatcher[T-2]
23:51
<@McMartin>
(So it won't know how big to make the elements of the array at compile time.)
23:51
<@McMartin>
I'll leave the discussion of ownership types, which you need to use to make such things workable, for another time.
23:53 You're now known as TheWatcher[zZzZ]
23:59
<@McMartin>
Also, after working through the design here, I'll add this kind of thing to the sort of thing that C++ is actually uniquely good at.
23:59
<@McMartin>
Because it hinges on the kind of capabilities that let you be C but with some actual structure imposed over it that vanishes once you hit the binary level.
--- Log closed Sun Sep 07 00:00:13 2008
code logs -> 2008 -> Sat, 06 Sep 2008< code.20080905.log - code.20080907.log >