Applications and the Difficulties of Portability?
insane_coder asks: "I'm a software developer who writes a lot of freeware utilities in C/C++ which are all cross platform and work well. Lately some of my users have been pestering me to stop wasting precious development time supporting minority OSs like Linux, and get more work done for the majority — the Windows users. Now all of my utilities are simple tools that perform various operations on files such as compression or rearranging. I've also made a few frontends for them using the excellent Qt library to allow the user to select a file and process using a simple GUI. In the dozens of applications I wrote, most of them several thousand lines long, I haven't written a single conditional for any particular OS. When I release, I just compile each app for all the OSs I have access to and post them on my website. I barely expend any effort at all to achieve portability. So the question I have to ask is: Why do the masses perceive portability as something that requires effort and a waste of time?"
"Most applications don't do anything fancy or need to talk to devices and therefor there is no need to do anything special other than compile them on a particular OS to run on that OS. So why are there so many simple apps using native APIs to do simple things like file reading instead of the standard ones? Why are we projecting an image that one must go out of their way or switch to a different language in order to achieve portability?"
How about because the differences are difficult to hide.
the API for getting the first post on slashdot is simple enough, who cares? :)
It's the Windows development tools. By default they generate code that uses tons of Windows-specific APIs that aren't portable to anything but another version of Windows (and sometimes not even then). If you start with OS-specific code, then yes supporting other OSes looks difficult. Combine this with Microsoft's business need to make portability look as difficult as possible to discourage developers from aiming for it and the results are predictable.
For the most part, portability isn't hard. You can write pretty much all the functionality of your software without getting into platform-specific issues. Generally, the higher the level of abstraction a languages is at (assembly C Python), the easier it gets. Of course, you do have to use standard APIs and avoid platform-specific ones (win32, GNU extensions, etc.) Things that have caused trouble for me in the past:
...
- Sockets (BSD sockets vs. Winsock's almost-compatible variant); this is not a problem in most higher level languages
- GUIs (there isn't really a standard; perhaps wxWidgets?)
- Threads (POSIX threads vs. whatever Windows has)
- Processes (fork, AFAIK, really doesn't exist on Windows)
If I need any functionality that isn't readily portable, I usually target POSIX or BSD, which makes my code portable to many *nix variants, and Windows using Cygwin.
Of course, there are also a whole bunch of cross-platform libraries out there, like glib, the APR, SDL, Qt,
Please correct me if I got my facts wrong.
If they won't believe or accept your response when you tell them how little effort portability requires, why should you care about their false perceptions? For instance, is it a concern that others will believe the non-programmer over you and make decisions which will have a negative impact on you?
Fuck Slashdot
Alternativly:
1. Attach wheels
The problem is, people expect computers to be hard. They expect that there is some knowledge that they should be looking for. Some users look for solutions to their problems on Google before (and often instead) checking the documentation. And then they write bugreports to the author and describe how their tried to avoid problems in long forgotten versions of the software because somebody described it in a blog.
My pet peeve is users asking "What am I doing wrong?" when reporting a real bug. Users expect to be wrong about computers.
This is just another case of people expecting things to be harder than they are. Plus a bit of jealousy towards the "minority OS" users who must be wasting time of the genius programmer. Deal with it. It's a psychological problem.
Inventions have long since reached their limit, and I see no hope for further development.-- Frontinus, 1st cent. AD
I personally agree that if you're going to release something command-line based, it shouldn't matter at all. I myself am a software developer, and while my applications are not cross-platform, I certainly appreciate those utilities that are. In my case, what I'm doing is not simple and highly specialized, so cross-platform doesn't do anything for me except make more work for no reason. My applications are not things that anybody else would find useful aside from the people I am making it for.
Most people, when they run an application on Windows, expect it to react in the same old Windows way. Many of cross-platform libraries do a poor job of doing that. I personally don't use GAIM because I can't stand the way it looks. Even though complaining about the ugliness of the GUI might seem stupid to some, it is a genuine problem with people. Clearly, it makes some form of different, as evidenced by the ever increasing "beautification" of window managers like KDE and Gnome.
It may be that this bugs me more than most precisely because I am a developer. It may be that it bugs ordinary people even more. I have no idea. But I think that increasingly the transparency of external libraries would probably help gain them acceptance. The problem is made even worse by libraries that clutter up your system by popping up and asking you to update, or add entries in your menus that you'll never need, as a user.
Because all they teach in schools now is java. They have all bought into Sun's propaganda. The students don't know any better and believe what they are told.
You are absolutely correct in your approach, well written C/C++ code will compile and run on just about any modern OS and results in the most efficient and fastest applications.
Another reply above also makes a good point that too many people depend on libraries and third party code that is specific to their development platform. Depending on third party code and libraries is absolutely foolish, however the majority of programmers expect a free lunch when it comes to writing applications and expect someone else to do all the work for them, then wonder why things go wrong.
You pose an excellent, yet rhetorical question and it illustrates perfectly the absurd redundancy of java which claims to be cross platform but really is not, all it does is waste system resources and ecourage you to depend on inefficient and probably broken classes written by other people.
Don't change a thing about how you work, it is the right way to go no matter what the java zealots tell you.
With a project of mine, I've had a ton of abuse at times. People telling me it's already been done a million times, that I'm duplicating effort needlessly, that I should just use a pre-existing solution to the problem, etc etc etc.
The bottom line is that around 99.9% of human beings are small minded, brainless insects who are utterly devoid of intelligence, initiative, self-responsibility, creativity, or vision, and who in general terms don't really have any terribly concrete reason to exist. The one thing that said individuals *are* unfailingly good at however is coming up with reasons why you shouldn't do whatever it is you are trying to, why it will fail, why it's already been done before, or why nobody has ever been able to succeed at it before and why do you think you're any different, etc. Some forms of this abuse unique to the Linux community also include particularly vitriolic condemnation of anyone seeking any form of financially gainful activity associated with Linux.
Slashdot itself is a particularly rich source for plentiful examples of these types of people, I've noticed.
Although the level of repetition with which you will encounter this condemnation makes doing so difficult, I urge you above all to ignore it. Realise that in virtually all cases it will come from people whose sole reason for breathing is to accelerate the degradation of the environment, and that as such, all listening to them will do is reduce the chances of you actually doing some genuine good.
If you're trying to accomplish something, realise that that in itself is an extremely reliable indication that you're an infinitely more intelligent and generally redeemable human being than those who are trying to dissuade you from a given objective. Looking at it from this perspective actually makes ignoring them a lot easier...you identify them as the vermin that they are, which then means that their opinion can likewise be summarily discarded.
"This is just another case of people expecting things to be harder than they are."
Like sex.
From the sound of the article/question, with their setup, it really doesn't seem like it is that big a deal to support multiple platforms. Plus, the knowledge is there, and they seem to enjoy it, its simple tools, etc. Why the hell not.
,but I remember even in Java a few years back, one had to add some specific arguments when running java apps so that the menu bar would be at the right place in OSX, otherwise it would end up more like KDE/WIndows/Gnome/etc, with everything inside the window by default.
Other environments (usualy very customer centric ones, let say consulting firms, with strict deadlines, marketing getting in the way, etc) and more complex applications with very specific needs, it becomes trickier. These are the environments where your job is hard even if you're only supporting one platform, and even using every single last specialised API the platform offers still let you wish for more. In those cases it becomes a bit more annoying to have to go with the lowest common denominator.
Then add to that that users of different platforms -expect- different things. It isn't the end of the world to make something that works on both OSX and Windows, for example. But users of both platforms expect certain different things. I don't know the status right now
And last, but the most important one, testing, QA, etc. Doing cross platform, no matter what you do (unless you only do HTML and target Firefox only or something) means testing on those platforms, if only to look. That means moving the files, booting up the virtual machine, or something, to check it out. If the app is remotly complex, that IS time consuming like hell.
So in the end, it really depends. If you release your app to the general public, then the advantages of cross platform often outweight the "cost", and its only a matter of time before we are -expected- to do it. When your audience is more limited though, you often benifit more from targeting one particular platform and optimising your workflow like crazy for it, the time saving is significant.
I agree with what you say up to a certain point. But for anything complicated, there are always things that require some non-portable extension. The most common one I find is interfacing with third party software. On Windows, these often require the use of COM (or ActiveX, or whatever the flavour of the month is).
Graham
Wrong story buddy.The story that you want to be inane in is here: http://slashdot.org/article.pl?sid=06/11/16/234022 4
What if the entire Universe were a chrooted environment with everything symlinked from the host?
I, of course, mean the "some" users who seem to think that they should dictate what platforms your freeware runs on. Really, there might be a valid argument if these people were paying you gobs of money on each release, but they aren't. Since it won't exactly hurt you financially, I don't see the issue with telling them to take a long hike off a short pier, or probably the better approach of "I'll give your suggestions the consideration they deserve. Thank you."
:-)
Alternately, here's a money-making opportunity... "Whichever platform raises the most money by $DATE will be the one that's supported"
"The urge to save humanity is almost always a false front for the urge to rule." --H.L. Mencken
I'm curious... assuming you really meant freeware (free-as-in-beer, closed source), how do you justify the price of the Qt libraries to yourself? I thought it was in the thousands per year per seat. Did you have a commercial license anyway for other projects, or are you just obscenely rich?
Basically, some people will say things like "Portability issues only happpen on Windows because of the use of Windows specific API.... and Linux somehow magically escapes this problem." I'm sure you are already aware that it is not true, because your code is portable and uses readily available libraries that do not vary in version, or in any major way at all from OS to OS. A buch of other people will say "All, code should be portable, because there is no reason for it to not be portable." And, I'm sure that from your post, this is the reasoning behind your question. So, here is a list of reasons that might help formulate an understanding of why some code is not portable... (bear in mind that a lot of my code is portable too, as that is usually indicative of good software practice) * Less portable code makes heavy use of API that is already written and tested inside the OS. * Less portable code can therefore be less expensive and quicker to produce. Depending on the circumstance this can be a long term and/or short term benefit. * Less portable code can be made to execute faster than portable code * Less portable code can be made to take advantage of hardware features that are only exposed through a specific API * Typically the most popular OS in the world is easier to program for by most programmers, thereby allowing everyone that is hired to get up to speed on the project more quickly. (Not a concern for a team of one) * Typically large projects need to make every advantage in efficiency that is readily available. This might or might not be dependant on the OS * Anything that has to do a lot of work with filesystems will need operating system dependant code to be written. There are faster file operation system calls for each specific OS. * Less portable code can be made smaller in size, by depending on libraries that are only available on a target OS. (As long as they are actually there!!!) For example in Windows you can take advantage of a bunch of API to change system settings like IIS settings, and smtp settings. In Linux you have to write code to manually change text files. Of course API are better here because then there is less chance messing up the format of the text file. And your code will work in the next version of the OS too. Your code will not work in the next version if you change the config files manually. In your case, you don't care because you are just writing little free utilities. In bigger enterprise level applications you need to care about things like this. There are many examples of needing to use API where-ever possible. More experience with bigger applications is the best way to get to this knowledge. Also, one final note. C is getting to be an old language now, and it is sad that any code written in C is not portable. Things that have been around that long, have workaround after workaround to make them keep from breaking. It almost requires effort to write C code that is not portable nowadays. Bad C code is still prevelant though. This is mostly due to the #define conditional that was included to make C a lasting language. It worked. Now let's be done with it. Moving forward, I would suggest a language that makes use of garbage collection as your next choice. Also, one with clean syntax and no workarounds already in place would be a good plan. These criterea make for a langauge that is more difficult to write stupid code in. If you ever have to maintain code, then these are good considerations. Here are some examples (in no specific oreder) Java, C#, PHP Here is a bad example C++
Does this apply to handheld devices as well?
I'm a software developer who writes a lot of freeware utilities
Fuck them. You're providing them with programs for free. Just because one platform has a majority of users shouldn't mean it gets all the attention.
If you were making a LIVING off of the products you produce, doing the opposite would be probably be the wisest course of action.
Registered Linux user #421033
Cross-platform is hard.
But Trolltech did all the work for you. They make it easy.
Anybody who has never experienced that may not believe it. Trolltech is hiding a lot from you. (This is a good thing.)
or
2. Use a large bulldozer
Caveat: If your app is command-line, then this isn't really an issue. (Well, it still sort-of is, in that DOS CLI apps have different mechanisms for help than Unix ones, but we'll ignore those details.)
The reason cross-platform is hard is because GUIs behave very differently from each other. To be a "correct" Mac OS program, you must support:
1) AppleScript, at least the bare minimum actions.
2) The Services menu. Many ported apps don't have it.
3) The integrated spell checker. Most ported apps don't have it. Including biggies like Microsoft Office. (Needless-to-say, Firefox also doesn't support the integrated spell checker.)
4) Verb dialog boxes. That is, no "yes/no" questions in dialogs, they must all be "Save" "Don't Save" (or similar.) In addition, the location of Ok and Cancel are different in different OSes.
5) Drag&Drop, another simple feature the majority of ported apps get wrong. (Note: this includes drag&drop text editing as well as dragging snippets to the desktop.)
6) Mac-like edit boxes. Here's an example ported apps almost always get wrong: if your cursor is at the bottom line, but in the middle of the text, and you hit the down arrow the cursor should move to the end of the bottom line. On Windows, it should do nothing. On Linux... well I have no clue if Linux has any standards for arrow behavior in edit boxes. (Firefox gets this wrong also, as do many, many apps.)
7) Standard Mac menu shortcuts. This is pretty easy since other OSes ripped-off most of Apple's shortcuts anyway.
8) Being responsive to sleep, hibernate and shut down requests from the OS. Every time I see OS X telling me that shutdown was cancelled because of some mis-behaving app I want to scream.
9) Not relying on any absolute paths other than those defined by the OS. Lot of apps get this wrong.
10) Using Apple's color picker, font picker, "Special Characters" picker, etc instead of your own. Many apps get this wrong.
I'm probably missing items on this list. In addition, Windows has items on its list different from the Macintosh list. (For instance, coping with Active Directory, having an installer.)
I can guarantee that your cross-platform framework gets at most half of these things right. The Java VM gets basically none of them right. Firefox gets like 3 of them right. The reason you think cross-platform development is easy is one or more of the following:
1) You don't bother to QA your product on Mac/Windows/whatever. (This is the most likely.)
2) Your programs have trivial GUIs and/or you don't give a whit about the quality of the GUI.
3) Your programs are CLIs and have no GUI at all. (Note that if this is the case, they're still probably wrong on DOS, which is quite different from Unix CLIs.)
Tell you what, the instant I see a single ported app to Mac OS X that actually looks and behaves like an OS X app, I'll eat my words and agree with you. But I don't think that'll happen.
Comment of the year
I've seen this happen to my posts if I get interrupted while writing a reply. Perhaps the index allocated to your comment is timed out and given away to someone else. Then you're reply gets shuffled onto a completely different article.
Vintage computer adverts: http://www.vintageadbrowser.com/computers-and-software-ads
Also, portability tends to ecourage modularity, which helps isolate bugs and make them less likely in the first place, since the modules are smaller and easier to reason about than large chunks of code.
PHEM - party like it's 1997-2003!
I think you sent that as "HTML formatted" -- which gave me one big line of unreadable-ness. I haven't actually read it yet, I'll respond in a minute. Here's how I think it's supposed to look:
Basically, some people will say things like "Portability issues only happpen on Windows because of the use of Windows specific API.... and Linux somehow magically escapes this problem."
I'm sure you are already aware that it is not true, because your code is portable and uses readily available libraries that do not vary in version, or in any major way at all from OS to OS.
A buch of other people will say "All, code should be portable, because there is no reason for it to not be portable."
And, I'm sure that from your post, this is the reasoning behind your question.
So, here is a list of reasons that might help formulate an understanding of why some code is not portable... (bear in mind that a lot of my code is portable too, as that is usually indicative of good software practice)
* Less portable code makes heavy use of API that is already written and tested inside the OS.
* Less portable code can therefore be less expensive and quicker to produce. Depending on the circumstance this can be a long term and/or short term benefit.
* Less portable code can be made to execute faster than portable code
* Less portable code can be made to take advantage of hardware features that are only exposed through a specific API
* Typically the most popular OS in the world is easier to program for by most programmers, thereby allowing everyone that is hired to get up to speed on the project more quickly. (Not a concern for a team of one)
* Typically large projects need to make every advantage in efficiency that is readily available. This might or might not be dependant on the OS
* Anything that has to do a lot of work with filesystems will need operating system dependant code to be written. There are faster file operation system calls for each specific OS.
* Less portable code can be made smaller in size, by depending on libraries that are only available on a target OS. (As long as they are actually there!!!)
For example in Windows you can take advantage of a bunch of API to change system settings like IIS settings, and smtp settings.
In Linux you have to write code to manually change text files. Of course API are better here because then there is less chance messing up the format of the text file. And your code will work in the next version of the OS too. Your code will not work in the next version if you change the config files manually. In your case, you don't care because you are just writing little free utilities. In bigger enterprise level applications you need to care about things like this. There are many examples of needing to use API where-ever possible. More experience with bigger applications is the best way to get to this knowledge.
Also, one final note. C is getting to be an old language now, and it is sad that any code written in C is not portable. Things that have been around that long, have workaround after workaround to make them keep from breaking. It almost requires effort to write C code that is not portable nowadays. Bad C code is still prevelant though. This is mostly due to the #define conditional that was included to make C a lasting language. It worked. Now let's be done with it.
Moving forward, I would suggest a language that makes use of garbage collection as your next choice. Also, one with clean syntax and no workarounds already in place would be a good plan. These criterea make for a langauge that is more difficult to write stupid code in. If you ever have to maintain code, then these are good considerations.
Here are some examples (in no specific oreder)
Java, C#, PHP
Here is a bad example
C++
Don't thank God, thank a doctor!
Open oource is by no means a garanty for portability. If someone releases the source code of an utility that's written with many Windows/Linux specific libraries or APIs, then it's not portable, open source or not. Yes, someone can pick it up and port it to another platform - but that is work and you won't know when that someone with the right knowledge and time at their hands will show up...
Actually I don't think to many people realize that QT is probably more portable than javascript.
Only 'flamers' flame!
Does slashdot hate my posts?
Linux does not magically escape the problem. However, Linux developers are much more likely to write portable apps, because they remember how much it sucks to have their OS be unsupported, so they will naturally want to support BSD and OS X also.
POSIX does help, however. NT was originally going to claim POSIX compliance, but now seems to deliberately break it.
I wouldn't claim that. For instance, modprobe has no reason to work on anything but Linux. Similarly, regedit has no reason to work on anything but Windows. However, I would suggest that most user-level apps could be portable, and the only question is whether it costs you anything. I believe you discuss costs below:
There's a lot of vagaries there. Let's get more specific:
Are you talking about the performance benefit gained by writing code that isn't as modular? Proper refactoring can have its own benefits, certainly in terms of cache coherency.
The only way you're right here is if we're talking about assembly-level optimizations. In this case, only a madman would use hand-coded assembly for more than the tightest of the tight loops, which means very little hand-coded assembly. Even here, I think it's still possible to be portable across OSes on the same arch, most of the time, and I have to wonder if this could be shunted off to a library, which could then be made platform-independent by doing similar optimizations on every platform.
For instance, if we're talking about games, the simple solution would be to use an existing engine, like the Quake4 engine, so someone else has already done the hand-optimization (as well as handled most of the other concerns), and you're automagically portable.
What kind of hardware features?
Unless you're talking about what I just was, the only way this is a problem is if you're writing a driver. Driver code is generally considered part of the OS, and thus not portable. And yet, nVidia still manages to make theirs mostly portable.
This depends on the size of a project, but most often, I find it's a much bigger job to get up to speed on the app than the environment. For instance, it's taking me far longer to learn Drupal than it took me to learn (ugh) PHP. And since it's cross-platform, the programmers can use whatever OS is easiest for them, so long as they don't screw it up for everyone else -- which is something they should already be trying to do, assuming you've already got a project.
Either you mean running speed, which we discussed above, or development speed. Development speed shouldn't really matter, as you should be able to mostly use the tools everyone's familiar with, although I can see problems with people
Don't thank God, thank a doctor!
In my experience, the discipline of cross-platform development is a great aid to the development of high-quality code. It's essential to have more than one unrelated compiler you use. For example, very often, one compiler or the other will be more picky about something (Intel has a nice message warning you of the lack of a virtual destructor in a case where it's needed, and GCC has a nice warning about failing to provide case:'s for all defined types in an enumerated switch. Furthermore, you get to take advantage of the different debugging tools available on the different platforms. For example, Microsoft's debugger lets you break when a given memory location is changed (maybe gdb does too -- I don't know), while Linux has the excellent valgrind for detecting invalid memory references. Some compilers do a better job than others of checking the types for varargs functions, e.g. printf. A library, which may allow bad input on one platform, may complain on another. Etc.
So, the demand for you to drop cross-platform development, in order to enable you to devote more resources to your Windows version, would likely have opposite to the intended effect. (that is, unless you're doing something especially OS-dependant, which it sounds like you're not)
- Chuck
Don't be stupid just because they are. Put up a cafepress page selling coffee mugs that say "I supported Insane Coder's Windows portability effort!" and price them at $29.99. Do the paypal button ( if you don't mind being associated with those criminals ) for those that don't want a concrete token of their idiocy. It won't cost you but a few minutes to set up those links, you won't have to devote any extra time to coding -- I advise you spend the money on BOOZE and HOOKERS.
ZSNES is written in almost all ASM (Last I saw? There were stirrings of C/C++ conversions, but the task was monumental). Insanely non-portable. I couldn't even read your post after that.
I hate grammar Nazi's.
Comment removed based on user account deletion
How about because the differences are difficult to hide.
...) while still providing the same functionality (... & Feel") on each platform. wyoGuide follows the simple principle: "Look == native, Feel == genereal".
That's not true, it's quite easy if one knows how. Just visit wyoGuide (http://wyoguide.sf.net/) and learn how an application gets a fitting native look ("Look
O. Wyss
See http://wyoguide.sf.net/papers/Cross-platform.html
Portability across different operating systems, such as you are doing, using some cross-platform tools/language, nowadays is pretty easy. I have to wonder, though, whether your code compiles and runs as nicely on different hardware platforms. Quite often, I've found that people have no idea about how to write, um, let's call it cross-processor code.
No, that's not really difficult either, it's just not something that you tend to be taught very much.
"I'm not much interested in interoperability. I want substitutability. I want to be able to throw your software out."
I'm sure the users of my cross-platform C++ application (hd24tools) wouldn't complain that it is supported on Linux. It *started* on Linux, because *I* needed it on Linux. I don't need any more argumentation than that to keep supporting it on Linux. It is making it available to the *other* platforms that costs (some) extra time.
Visit http://ringbreak.dnd.utwente.nl/~mrjb/growingbettersoftware to download your free copy of the book
Mod this Up this is a Excellent Perspective!
I used WxWidgets (with C/C++) for a cross-platform commercial application that runs on Windows, MacOSX and Linux. It was a smooth process.
I used wx-devcpp for IDE/RAD development. For the MacOSX I used XCode (no problems). And for Linux, just as few changes to the MacOSX Makefile and that was it.
I released it only for Windows, but I have it working on MacOSX and Linux just as well. For the time being there is no market (no demand) for this application for MacOSX and Linux, but if that changes I can release today.
This would only apply if you know how to use the windows visual studio environment.
I would say most people speaking of such things are the ones used to telling or being told
"I need this to be done in 2 weeks and has to do everything even clean the windows
in my apartment" so you go to your visual studio toolbox and start to program something
they need that ties into all the other apps you created and with the push of the button
you create through predefined templates and code smith add-ins a full app that does what
they want and talks with the other programs in about 2 hours and leaves you about 2 weeks
to play golf.
"Plan your work and work your plan!"
"Lately some of my users have been pestering me to stop wasting precious development time supporting minority OSs like Linux, and get more work done for the majority -- the Windows users. {snip} Why do the masses perceive portability as something that requires effort and a waste of time?"
"some of users" is not "the masses". Obviously you are being subjected to a Microsoft plot!
... only stupid answers, but I really wonder why you ask that?
...
... the same is true for Mac programmers and most linux programmers use either what KDE offers or what gnome offers (well, likely not for files but for everything else).
... that is what bothers me. They are the same ppl who scream how complicated Java Swing is ... but the only thing they can do is click widgets together in an IDE and cut/copy the same event handling code for their same buttons over and over again from old code.
Why do the masses perceive portability as something that requires effort and a waste of time?
Because:
I've also made a few frontends for them using the excellent Qt library
Most programmers only profram for ONE platform. If its Windows they use windows APIs, even for somewthing so simple like opening a file they don't use fopen but OpenFile
Result: not the fact that they bother you not to care for portability, but the fact that they think the API (don't call it framework please) is as good or even better or even simpler than the Qt framework
angel'o'sphere
Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.